atlan-application-sdk 2.1.1__tar.gz → 2.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- atlan_application_sdk-2.2.0/.github/release_notes.md +8 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/CHANGELOG.md +10 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/PKG-INFO +5 -1
- atlan_application_sdk-2.2.0/application_sdk/clients/azure/__init__.py +6 -0
- atlan_application_sdk-2.2.0/application_sdk/clients/azure/auth.py +288 -0
- atlan_application_sdk-2.2.0/application_sdk/clients/azure/client.py +336 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/common/error_codes.py +9 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/server/fastapi/__init__.py +30 -1
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/server/fastapi/models.py +62 -1
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/transformers/query/__init__.py +26 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/version.py +1 -1
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/components/eventstore.yaml +1 -1
- atlan_application_sdk-2.2.0/components/pubsub.yaml +41 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/docs/docs/concepts/server.md +86 -1
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/pyproject.toml +6 -1
- atlan_application_sdk-2.2.0/tests/unit/clients/test_azure_auth.py +177 -0
- atlan_application_sdk-2.2.0/tests/unit/clients/test_azure_client.py +246 -0
- atlan_application_sdk-2.2.0/tests/unit/server/fastapi/test_fastapi.py +911 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/transformers/query/test_sql_transformer.py +18 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/uv.lock +292 -182
- atlan_application_sdk-2.1.1/.github/release_notes.md +0 -8
- atlan_application_sdk-2.1.1/tests/unit/server/fastapi/test_fastapi.py +0 -192
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.cursor/BUGBOT.md +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.cursor/rules/commits.mdc +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.cursor/rules/documentation.mdc +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.cursor/rules/exception-handling.mdc +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.cursor/rules/guidelines.mdc +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.cursor/rules/logging.mdc +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.cursor/rules/performance.mdc +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.cursor/rules/setup.mdc +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.cursor/rules/standards.mdc +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.cursor/rules/testing.mdc +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.dockerignore +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.env.example +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/CODEOWNERS +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/ISSUE_TEMPLATE/bug_report.yaml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/ISSUE_TEMPLATE/config.yaml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/ISSUE_TEMPLATE/feature_request.yaml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/actions/docgen/action.yaml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/actions/doclint/action.yaml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/actions/docstring-coverage/action.yaml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/actions/e2e-apps/action.yaml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/actions/e2e-examples/action.yaml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/actions/secure-build-push-apps/action.yaml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/actions/setup-deps/action.yaml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/actions/sync-branches/action.yaml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/actions/trivy/action.yaml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/actions/trivy-container/action.yaml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/actions/unit-tests/action.yaml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/dependabot.yaml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/pull_request_template.md +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/scripts/extract_release_notes.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/scripts/release.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/scripts/trivy-to-markdown.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/scripts/update_changelog.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/styles/Microsoft/AMPM.yml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/styles/Microsoft/Accessibility.yml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/styles/Microsoft/Acronyms.yml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/styles/Microsoft/Adverbs.yml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/styles/Microsoft/Auto.yml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/styles/Microsoft/Avoid.yml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/styles/Microsoft/Contractions.yml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/styles/Microsoft/Dashes.yml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/styles/Microsoft/DateFormat.yml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/styles/Microsoft/DateNumbers.yml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/styles/Microsoft/DateOrder.yml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/styles/Microsoft/Ellipses.yml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/styles/Microsoft/FirstPerson.yml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/styles/Microsoft/Foreign.yml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/styles/Microsoft/Gender.yml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/styles/Microsoft/GenderBias.yml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/styles/Microsoft/GeneralURL.yml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/styles/Microsoft/HeadingAcronyms.yml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/styles/Microsoft/HeadingColons.yml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/styles/Microsoft/HeadingPunctuation.yml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/styles/Microsoft/Headings.yml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/styles/Microsoft/Hyphens.yml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/styles/Microsoft/Negative.yml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/styles/Microsoft/Ordinal.yml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/styles/Microsoft/OxfordComma.yml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/styles/Microsoft/Passive.yml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/styles/Microsoft/Percentages.yml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/styles/Microsoft/Plurals.yml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/styles/Microsoft/Quotes.yml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/styles/Microsoft/RangeTime.yml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/styles/Microsoft/Semicolon.yml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/styles/Microsoft/SentenceLength.yml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/styles/Microsoft/Spacing.yml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/styles/Microsoft/Suspended.yml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/styles/Microsoft/Terms.yml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/styles/Microsoft/URLFormat.yml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/styles/Microsoft/Units.yml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/styles/Microsoft/Vocab.yml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/styles/Microsoft/We.yml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/styles/Microsoft/Wordiness.yml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/styles/Microsoft/meta.json +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/styles/config/vocabularies/deviations/accept.txt +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/styles/config/vocabularies/deviations/reject.txt +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/workflow-templates/checks.properties.json +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/workflow-templates/checks.yaml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/workflow-templates/codeql.properties.json +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/workflow-templates/codeql.yaml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/workflow-templates/dependency-review.properties.json +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/workflow-templates/dependency-review.yml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/workflow-templates/stale.properties.json +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/workflow-templates/stale.yml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/workflow-templates/trivy-container.properties.json +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/workflow-templates/trivy-container.yaml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/workflow-templates/trivy.properties.json +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/workflow-templates/trivy.yaml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/workflows/build-image.yaml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/workflows/codeql.yaml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/workflows/pull_request.yaml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/workflows/push.yaml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/workflows/release.yaml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/workflows/scale-tests.yaml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/workflows/schedule.yaml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/workflows/tag-and-publish.yaml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/workflows/trivy-container.yaml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.github/workflows/verify-snyk-status.yml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.gitignore +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.pre-commit-config.yaml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/.vscode/launch.json +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/CODE_OF_CONDUCT.md +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/CONTRIBUTING.md +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/Dockerfile +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/LICENSE +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/NOTICE +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/README.md +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/SECURITY.md +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/activities/.cursor/BUGBOT.md +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/activities/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/activities/common/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/activities/common/models.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/activities/common/sql_utils.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/activities/common/utils.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/activities/lock_management.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/activities/metadata_extraction/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/activities/metadata_extraction/base.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/activities/metadata_extraction/rest.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/activities/metadata_extraction/sql.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/activities/query_extraction/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/activities/query_extraction/sql.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/application/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/application/metadata_extraction/sql.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/clients/.cursor/BUGBOT.md +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/clients/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/clients/atlan.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/clients/atlan_auth.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/clients/base.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/clients/models.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/clients/redis.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/clients/sql.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/clients/temporal.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/clients/utils.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/clients/workflow.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/common/.cursor/BUGBOT.md +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/common/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/common/aws_utils.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/common/file_converter.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/common/types.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/common/utils.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/constants.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/decorators/.cursor/BUGBOT.md +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/decorators/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/decorators/locks.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/decorators/mcp_tool.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/docgen/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/docgen/exporters/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/docgen/exporters/mkdocs.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/docgen/models/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/docgen/models/export/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/docgen/models/export/page.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/docgen/models/manifest/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/docgen/models/manifest/customer.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/docgen/models/manifest/internal.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/docgen/models/manifest/metadata.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/docgen/models/manifest/page.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/docgen/models/manifest/section.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/docgen/parsers/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/docgen/parsers/directory.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/docgen/parsers/manifest.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/handlers/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/handlers/base.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/handlers/sql.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/interceptors/.cursor/BUGBOT.md +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/interceptors/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/interceptors/cleanup.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/interceptors/correlation_context.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/interceptors/events.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/interceptors/lock.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/interceptors/models.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/io/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/io/json.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/io/parquet.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/io/utils.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/observability/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/observability/context.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/observability/decorators/observability_decorator.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/observability/logger_adaptor.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/observability/metrics_adaptor.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/observability/observability.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/observability/traces_adaptor.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/observability/utils.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/server/.cursor/BUGBOT.md +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/server/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/server/fastapi/middleware/logmiddleware.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/server/fastapi/middleware/metrics.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/server/fastapi/routers/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/server/fastapi/routers/server.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/server/fastapi/utils.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/server/mcp/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/server/mcp/models.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/server/mcp/server.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/services/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/services/_utils.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/services/atlan_storage.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/services/eventstore.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/services/objectstore.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/services/secretstore.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/services/statestore.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/test_utils/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/test_utils/e2e/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/test_utils/e2e/base.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/test_utils/e2e/client.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/test_utils/e2e/conftest.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/test_utils/e2e/utils.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/test_utils/hypothesis/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/test_utils/hypothesis/strategies/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/test_utils/hypothesis/strategies/clients/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/test_utils/hypothesis/strategies/clients/sql.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/test_utils/hypothesis/strategies/common/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/test_utils/hypothesis/strategies/common/logger.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/test_utils/hypothesis/strategies/handlers/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/test_utils/hypothesis/strategies/handlers/sql/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/test_utils/hypothesis/strategies/handlers/sql/sql_metadata.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/test_utils/hypothesis/strategies/handlers/sql/sql_preflight.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/test_utils/hypothesis/strategies/inputs/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/test_utils/hypothesis/strategies/inputs/json_input.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/test_utils/hypothesis/strategies/inputs/parquet_input.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/test_utils/hypothesis/strategies/outputs/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/test_utils/hypothesis/strategies/outputs/json_output.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/test_utils/hypothesis/strategies/outputs/statestore.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/test_utils/hypothesis/strategies/server/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/test_utils/hypothesis/strategies/server/fastapi/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/test_utils/hypothesis/strategies/sql_client.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/test_utils/hypothesis/strategies/temporal.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/test_utils/scale_data_generator/README.md +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/test_utils/scale_data_generator/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/test_utils/scale_data_generator/config_loader.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/test_utils/scale_data_generator/data_generator.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/test_utils/scale_data_generator/driver.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/test_utils/scale_data_generator/examples/config.yaml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/test_utils/scale_data_generator/output_handler/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/test_utils/scale_data_generator/output_handler/base.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/test_utils/scale_data_generator/output_handler/csv_handler.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/test_utils/scale_data_generator/output_handler/json_handler.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/test_utils/scale_data_generator/output_handler/parquet_handler.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/test_utils/workflow_monitoring.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/transformers/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/transformers/atlas/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/transformers/atlas/sql.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/transformers/common/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/transformers/common/utils.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/transformers/query/templates/column.yaml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/transformers/query/templates/database.yaml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/transformers/query/templates/extras-procedure.yaml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/transformers/query/templates/function.yaml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/transformers/query/templates/schema.yaml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/transformers/query/templates/table.yaml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/transformers/query/templates/tag_attachment.yaml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/worker.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/workflows/.cursor/BUGBOT.md +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/workflows/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/workflows/metadata_extraction/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/workflows/metadata_extraction/sql.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/workflows/query_extraction/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/application_sdk/workflows/query_extraction/sql.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/components/README.md +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/components/atlan-storage.yaml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/components/aws-secrets.yaml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/components/configuration.yaml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/components/deployment-secrets.yaml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/components/objectstore.yaml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/components/secretstore.yaml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/components/statestore.yaml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/docs/docs/concepts/API.md +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/docs/docs/concepts/activities.md +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/docs/docs/concepts/application.md +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/docs/docs/concepts/application_sql.md +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/docs/docs/concepts/atlanupload.md +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/docs/docs/concepts/clients.md +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/docs/docs/concepts/common.md +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/docs/docs/concepts/handlers.md +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/docs/docs/concepts/inputs.md +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/docs/docs/concepts/mcp.md +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/docs/docs/concepts/output_paths.md +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/docs/docs/concepts/outputs.md +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/docs/docs/concepts/services.md +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/docs/docs/concepts/temporal_auth.md +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/docs/docs/concepts/worker.md +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/docs/docs/concepts/workflows.md +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/docs/docs/configuration.md +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/docs/docs/guides/architecture.md +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/docs/docs/guides/atlantis.md +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/docs/docs/guides/best-practices.md +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/docs/docs/guides/getting-started.md +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/docs/docs/guides/index.md +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/docs/docs/guides/secretstores.md +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/docs/docs/guides/sql-application-guide.md +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/docs/docs/guides/test-framework.md +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/docs/docs/index.md +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/docs/docs/setup/LINUX.md +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/docs/docs/setup/MAC.md +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/docs/docs/setup/WINDOWS.md +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/docs/docs/setup/troubleshooting.md +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/docs/docs/static/assets/logo.svg +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/docs/docs/static/images/phoenix-sdk-featureset.png +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/docs/docs/static/javascripts/mathjax.js +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/docs/docs/static/stylesheets/extra.css +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/docs/mkdocs.yml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/examples/README.md +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/examples/application_custom_fastapi.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/examples/application_fastapi.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/examples/application_hello_world.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/examples/application_sql.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/examples/application_sql_miner.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/examples/application_sql_with_custom_pyatlan_transformer.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/examples/application_sql_with_custom_transformer.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/examples/run_examples.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/examples/sql_query_templates/database.yaml +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/.cursor/BUGBOT.md +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/conftest.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/activities/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/activities/common/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/activities/common/test_sql_utils.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/activities/common/test_utils.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/activities/metadata_extraction/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/activities/metadata_extraction/test_sql.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/activities/query_extraction/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/activities/test_activities.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/activities/test_lock_management.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/application/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/application/metadata_extraction/test_sql.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/application/test_application.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/clients/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/clients/test_async_sql_client.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/clients/test_atlan_auth.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/clients/test_atlan_client.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/clients/test_atlanauth.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/clients/test_base_client.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/clients/test_redis_client.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/clients/test_sql_client.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/clients/test_temporal_client.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/common/test_aws_utils.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/common/test_credential_utils.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/common/test_file_converter.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/common/test_utils.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/common/test_utils_file_discovery.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/decorators/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/decorators/test_mcp_tool.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/docgen/parsers/test_directory_parser.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/docgen/parsers/test_manifest_parser.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/handlers/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/handlers/sql/test_auth.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/handlers/sql/test_check_schemas_and_databases.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/handlers/sql/test_extract_allowed_schemas.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/handlers/sql/test_metadata.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/handlers/sql/test_preflight_check.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/handlers/sql/test_prepare_metadata.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/handlers/sql/test_tables_check.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/handlers/sql/test_validate_filters.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/handlers/test_base_handler.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/interceptors/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/interceptors/test_correlation_context.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/io/readers/test_json_reader.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/io/readers/test_parquet_reader.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/io/test_base_io.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/io/writers/test_json_writer.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/io/writers/test_parquet_writer.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/observability/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/observability/test_logger_adaptor.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/observability/test_metrics_adaptor.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/observability/test_traces_adaptor.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/server/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/server/fastapi/routers/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/server/fastapi/routers/server.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/server/mcp/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/server/mcp/test_mcp_server.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/services/test_atlan_storage.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/services/test_eventstore.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/services/test_objectstore.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/services/test_statestore.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/test_worker.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/transformers/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/transformers/atlas/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/transformers/atlas/resources/raw_columns.json +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/transformers/atlas/resources/raw_databases.json +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/transformers/atlas/resources/raw_functions.json +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/transformers/atlas/resources/raw_procedures.json +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/transformers/atlas/resources/raw_schemas.json +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/transformers/atlas/resources/raw_tables.json +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/transformers/atlas/resources/transformed_columns.json +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/transformers/atlas/resources/transformed_databases.json +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/transformers/atlas/resources/transformed_functions.json +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/transformers/atlas/resources/transformed_procedures.json +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/transformers/atlas/resources/transformed_schemas.json +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/transformers/atlas/resources/transformed_tables.json +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/transformers/atlas/test_column.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/transformers/atlas/test_database.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/transformers/atlas/test_function.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/transformers/atlas/test_procedure.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/transformers/atlas/test_schema.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/transformers/atlas/test_table.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/transformers/query/resources/raw/column.json +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/transformers/query/resources/raw/database.json +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/transformers/query/resources/raw/extras-procedure.json +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/transformers/query/resources/raw/function.json +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/transformers/query/resources/raw/schema.json +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/transformers/query/resources/raw/table.json +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/transformers/query/resources/transformed/column.json +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/transformers/query/resources/transformed/database.json +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/transformers/query/resources/transformed/extras-procedure.json +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/transformers/query/resources/transformed/function.json +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/transformers/query/resources/transformed/schema.json +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/transformers/query/resources/transformed/table.json +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/transformers/query/test_sql_transformer_output_validation.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/workflows/metadata_extraction/test_sql_workflow.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/workflows/query_extraction/__init__.py +0 -0
- {atlan_application_sdk-2.1.1 → atlan_application_sdk-2.2.0}/tests/unit/workflows/query_extraction/test_sql.py +0 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
## v2.2.0 (January 14, 2026)
|
|
2
|
+
|
|
3
|
+
Full Changelog: https://github.com/atlanhq/application-sdk/compare/v2.1.1...v2.2.0
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
- added Azure specific client authentication (#619) (by @rupali-atlan in [37b2e19](https://github.com/atlanhq/application-sdk/commit/37b2e19))
|
|
8
|
+
- Using Pubsub for message processors (#898) (by @niteesh-atlan in [f87f583](https://github.com/atlanhq/application-sdk/commit/f87f583))
|
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v2.2.0 (January 14, 2026)
|
|
4
|
+
|
|
5
|
+
Full Changelog: https://github.com/atlanhq/application-sdk/compare/v2.1.1...v2.2.0
|
|
6
|
+
|
|
7
|
+
### Features
|
|
8
|
+
|
|
9
|
+
- added Azure specific client authentication (#619) (by @rupali-atlan in [37b2e19](https://github.com/atlanhq/application-sdk/commit/37b2e19))
|
|
10
|
+
- Using Pubsub for message processors (#898) (by @niteesh-atlan in [f87f583](https://github.com/atlanhq/application-sdk/commit/f87f583))
|
|
11
|
+
|
|
12
|
+
|
|
3
13
|
## v2.1.1 (January 08, 2026)
|
|
4
14
|
|
|
5
15
|
Full Changelog: https://github.com/atlanhq/application-sdk/compare/v2.1.0...v2.1.1
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: atlan-application-sdk
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.2.0
|
|
4
4
|
Summary: Atlan Application SDK is a Python library for developing applications on the Atlan Platform
|
|
5
5
|
Project-URL: Repository, https://github.com/atlanhq/application-sdk
|
|
6
6
|
Project-URL: Documentation, https://github.com/atlanhq/application-sdk/README.md
|
|
@@ -30,6 +30,10 @@ Requires-Dist: pyatlan<8.5.0,>=8.0.2
|
|
|
30
30
|
Requires-Dist: pydantic<2.13.0,>=2.10.6
|
|
31
31
|
Requires-Dist: python-dotenv<1.3.0,>=1.1.0
|
|
32
32
|
Requires-Dist: uvloop<0.23.0,>=0.21.0; sys_platform != 'win32'
|
|
33
|
+
Provides-Extra: azure
|
|
34
|
+
Requires-Dist: azure-identity>=1.15.0; extra == 'azure'
|
|
35
|
+
Requires-Dist: azure-storage-blob>=12.19.0; extra == 'azure'
|
|
36
|
+
Requires-Dist: azure-storage-file-datalake>=12.19.0; extra == 'azure'
|
|
33
37
|
Provides-Extra: daft
|
|
34
38
|
Requires-Dist: daft<0.8.0,>=0.7.1; extra == 'daft'
|
|
35
39
|
Provides-Extra: distributed-lock
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Azure authentication provider for the application-sdk framework.
|
|
3
|
+
|
|
4
|
+
This module provides the AzureAuthProvider class that handles Azure
|
|
5
|
+
Service Principal authentication for the application-sdk framework.
|
|
6
|
+
|
|
7
|
+
Example:
|
|
8
|
+
>>> from application_sdk.clients.azure.auth import AzureAuthProvider
|
|
9
|
+
>>> import asyncio
|
|
10
|
+
>>>
|
|
11
|
+
>>> # Create authentication provider
|
|
12
|
+
>>> auth_provider = AzureAuthProvider()
|
|
13
|
+
>>>
|
|
14
|
+
>>> # Authenticate with Service Principal credentials
|
|
15
|
+
>>> credentials = {
|
|
16
|
+
... "tenant_id": "your-tenant-id",
|
|
17
|
+
... "client_id": "your-client-id",
|
|
18
|
+
... "client_secret": "your-client-secret"
|
|
19
|
+
... }
|
|
20
|
+
>>>
|
|
21
|
+
>>> # Create credential
|
|
22
|
+
>>> credential = await auth_provider.create_credential(
|
|
23
|
+
... auth_type="service_principal",
|
|
24
|
+
... credentials=credentials
|
|
25
|
+
... )
|
|
26
|
+
>>>
|
|
27
|
+
>>> # Alternative credential key formats are also supported
|
|
28
|
+
>>> alt_credentials = {
|
|
29
|
+
... "tenantId": "your-tenant-id", # camelCase
|
|
30
|
+
... "clientId": "your-client-id", # camelCase
|
|
31
|
+
... "clientSecret": "your-client-secret" # camelCase
|
|
32
|
+
... }
|
|
33
|
+
>>>
|
|
34
|
+
>>> credential = await auth_provider.create_credential(
|
|
35
|
+
... auth_type="service_principal",
|
|
36
|
+
... credentials=alt_credentials
|
|
37
|
+
... )
|
|
38
|
+
>>>
|
|
39
|
+
>>> # Error handling for missing credentials
|
|
40
|
+
>>> try:
|
|
41
|
+
... await auth_provider.create_credential(
|
|
42
|
+
... auth_type="service_principal",
|
|
43
|
+
... credentials={"tenant_id": "only-tenant"} # Missing client_id and client_secret
|
|
44
|
+
... )
|
|
45
|
+
... except CommonError as e:
|
|
46
|
+
... print(f"Authentication failed: {e}")
|
|
47
|
+
... # Output: Authentication failed: Missing required credential keys: client_id, client_secret
|
|
48
|
+
>>>
|
|
49
|
+
>>> # Unsupported authentication type
|
|
50
|
+
>>> try:
|
|
51
|
+
... await auth_provider.create_credential(
|
|
52
|
+
... auth_type="unsupported_type",
|
|
53
|
+
... credentials=credentials
|
|
54
|
+
... )
|
|
55
|
+
... except CommonError as e:
|
|
56
|
+
... print(f"Authentication failed: {e}")
|
|
57
|
+
... # Output: Authentication failed: Only 'service_principal' authentication is supported. Received: unsupported_type
|
|
58
|
+
"""
|
|
59
|
+
|
|
60
|
+
from typing import Any, Dict, Optional
|
|
61
|
+
|
|
62
|
+
from azure.core.credentials import TokenCredential
|
|
63
|
+
from azure.core.exceptions import ClientAuthenticationError
|
|
64
|
+
from azure.identity import ClientSecretCredential
|
|
65
|
+
from pydantic import BaseModel, ConfigDict, Field, ValidationError
|
|
66
|
+
|
|
67
|
+
from application_sdk.clients.azure import AZURE_MANAGEMENT_API_ENDPOINT
|
|
68
|
+
from application_sdk.common.error_codes import CommonError
|
|
69
|
+
from application_sdk.common.utils import run_sync
|
|
70
|
+
from application_sdk.observability.logger_adaptor import get_logger
|
|
71
|
+
|
|
72
|
+
logger = get_logger(__name__)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
class ServicePrincipalCredentials(BaseModel):
|
|
76
|
+
"""
|
|
77
|
+
Pydantic model for Azure Service Principal credentials.
|
|
78
|
+
|
|
79
|
+
Supports both snake_case and camelCase field names through field aliases.
|
|
80
|
+
All fields are required for service principal authentication.
|
|
81
|
+
|
|
82
|
+
Attributes:
|
|
83
|
+
tenant_id: Azure tenant ID (also accepts 'tenantId').
|
|
84
|
+
client_id: Azure client ID (also accepts 'clientId').
|
|
85
|
+
client_secret: Azure client secret (also accepts 'clientSecret').
|
|
86
|
+
"""
|
|
87
|
+
|
|
88
|
+
tenant_id: str = Field(
|
|
89
|
+
...,
|
|
90
|
+
alias="tenantId",
|
|
91
|
+
description="Azure tenant ID for service principal authentication",
|
|
92
|
+
)
|
|
93
|
+
client_id: str = Field(
|
|
94
|
+
...,
|
|
95
|
+
alias="clientId",
|
|
96
|
+
description="Azure client ID for service principal authentication",
|
|
97
|
+
)
|
|
98
|
+
client_secret: str = Field(
|
|
99
|
+
...,
|
|
100
|
+
alias="clientSecret",
|
|
101
|
+
description="Azure client secret for service principal authentication",
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
model_config = ConfigDict(
|
|
105
|
+
populate_by_name=True, # Allow both field name and alias
|
|
106
|
+
extra="ignore", # Ignore additional fields (Azure client may need extra fields like storage_account_name, network_config, etc.)
|
|
107
|
+
validate_assignment=True, # Validate on assignment
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
class AzureAuthProvider:
|
|
112
|
+
"""
|
|
113
|
+
Azure authentication provider for handling Service Principal authentication.
|
|
114
|
+
|
|
115
|
+
This class provides a unified interface for creating Azure credentials
|
|
116
|
+
using Service Principal authentication with Azure SDK.
|
|
117
|
+
|
|
118
|
+
Supported authentication method:
|
|
119
|
+
- service_principal: Using client ID, client secret, and tenant ID
|
|
120
|
+
"""
|
|
121
|
+
|
|
122
|
+
def __init__(self):
|
|
123
|
+
"""Initialize the Azure authentication provider."""
|
|
124
|
+
pass
|
|
125
|
+
|
|
126
|
+
async def create_credential(
|
|
127
|
+
self,
|
|
128
|
+
auth_type: str = "service_principal",
|
|
129
|
+
credentials: Optional[Dict[str, Any]] = None,
|
|
130
|
+
) -> TokenCredential:
|
|
131
|
+
"""
|
|
132
|
+
Create Azure credential using Service Principal authentication.
|
|
133
|
+
|
|
134
|
+
Args:
|
|
135
|
+
auth_type (str): Type of authentication to use.
|
|
136
|
+
Currently only supports 'service_principal'.
|
|
137
|
+
credentials (Optional[Dict[str, Any]]): Service Principal credentials.
|
|
138
|
+
Required fields: tenant_id, client_id, client_secret.
|
|
139
|
+
|
|
140
|
+
Returns:
|
|
141
|
+
TokenCredential: Azure credential instance.
|
|
142
|
+
|
|
143
|
+
Raises:
|
|
144
|
+
CommonError: If authentication type is not supported or credentials are invalid.
|
|
145
|
+
ClientAuthenticationError: If credential creation fails.
|
|
146
|
+
"""
|
|
147
|
+
try:
|
|
148
|
+
logger.debug(f"Creating Azure credential with auth type: {auth_type}")
|
|
149
|
+
|
|
150
|
+
if auth_type.lower() != "service_principal":
|
|
151
|
+
raise CommonError(
|
|
152
|
+
f"{CommonError.CREDENTIALS_PARSE_ERROR}: "
|
|
153
|
+
f"Only 'service_principal' authentication is supported. "
|
|
154
|
+
f"Received: {auth_type}"
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
if not credentials:
|
|
158
|
+
raise CommonError(
|
|
159
|
+
f"{CommonError.CREDENTIALS_PARSE_ERROR}: "
|
|
160
|
+
"Credentials required for service principal authentication"
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
return await self._create_service_principal_credential(credentials)
|
|
164
|
+
|
|
165
|
+
except ClientAuthenticationError as e:
|
|
166
|
+
logger.error(f"Azure authentication failed: {str(e)}")
|
|
167
|
+
raise CommonError(f"{CommonError.AZURE_CREDENTIAL_ERROR}: {str(e)}")
|
|
168
|
+
except ValueError as e:
|
|
169
|
+
logger.error(f"Invalid Azure credential parameters: {str(e)}")
|
|
170
|
+
raise CommonError(
|
|
171
|
+
f"{CommonError.CREDENTIALS_PARSE_ERROR}: Invalid credential parameters - {str(e)}"
|
|
172
|
+
)
|
|
173
|
+
except TypeError as e:
|
|
174
|
+
logger.error(f"Wrong Azure credential parameter types: {str(e)}")
|
|
175
|
+
raise CommonError(
|
|
176
|
+
f"{CommonError.CREDENTIALS_PARSE_ERROR}: Invalid credential parameter types - {str(e)}"
|
|
177
|
+
)
|
|
178
|
+
except Exception as e:
|
|
179
|
+
logger.error(f"Unexpected error creating Azure credential: {str(e)}")
|
|
180
|
+
raise CommonError(
|
|
181
|
+
f"{CommonError.CREDENTIALS_PARSE_ERROR}: Unexpected error - {str(e)}"
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
async def _create_service_principal_credential(
|
|
185
|
+
self, credentials: Dict[str, Any]
|
|
186
|
+
) -> ClientSecretCredential:
|
|
187
|
+
"""
|
|
188
|
+
Create service principal credential.
|
|
189
|
+
|
|
190
|
+
Args:
|
|
191
|
+
credentials (Dict[str, Any]): Service principal credentials.
|
|
192
|
+
Must include tenant_id, client_id, and client_secret.
|
|
193
|
+
|
|
194
|
+
Returns:
|
|
195
|
+
ClientSecretCredential: Service principal credential.
|
|
196
|
+
|
|
197
|
+
Raises:
|
|
198
|
+
CommonError: If required credentials are missing or invalid.
|
|
199
|
+
"""
|
|
200
|
+
if not credentials:
|
|
201
|
+
raise CommonError(
|
|
202
|
+
f"{CommonError.CREDENTIALS_PARSE_ERROR}: "
|
|
203
|
+
"Credentials required for service principal authentication"
|
|
204
|
+
)
|
|
205
|
+
|
|
206
|
+
try:
|
|
207
|
+
# Validate credentials using Pydantic model
|
|
208
|
+
validated_credentials = ServicePrincipalCredentials(**credentials)
|
|
209
|
+
except ValidationError as e:
|
|
210
|
+
# Pydantic provides detailed error messages for all validation errors
|
|
211
|
+
# Format errors into a user-friendly message
|
|
212
|
+
error_details = "; ".join(
|
|
213
|
+
[
|
|
214
|
+
f"{'.'.join(str(loc) for loc in err['loc'])}: {err['msg']}"
|
|
215
|
+
for err in e.errors()
|
|
216
|
+
]
|
|
217
|
+
)
|
|
218
|
+
error_message = f"Invalid credential parameters: {error_details}"
|
|
219
|
+
logger.error(f"Azure credential validation failed: {error_message}")
|
|
220
|
+
raise CommonError(f"{CommonError.CREDENTIALS_PARSE_ERROR}: {error_message}")
|
|
221
|
+
|
|
222
|
+
logger.debug(
|
|
223
|
+
f"Creating service principal credential for tenant: {validated_credentials.tenant_id}"
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
try:
|
|
227
|
+
return await run_sync(ClientSecretCredential)(
|
|
228
|
+
validated_credentials.tenant_id,
|
|
229
|
+
validated_credentials.client_id,
|
|
230
|
+
validated_credentials.client_secret,
|
|
231
|
+
)
|
|
232
|
+
except ValueError as e:
|
|
233
|
+
logger.error(f"Invalid Azure credential parameters: {str(e)}")
|
|
234
|
+
raise CommonError(
|
|
235
|
+
f"{CommonError.CREDENTIALS_PARSE_ERROR}: Invalid credential parameters - {str(e)}"
|
|
236
|
+
)
|
|
237
|
+
except TypeError as e:
|
|
238
|
+
logger.error(f"Wrong Azure credential parameter types: {str(e)}")
|
|
239
|
+
raise CommonError(
|
|
240
|
+
f"{CommonError.CREDENTIALS_PARSE_ERROR}: Invalid credential parameter types - {str(e)}"
|
|
241
|
+
)
|
|
242
|
+
except ClientAuthenticationError as e:
|
|
243
|
+
logger.error(f"Azure authentication failed: {str(e)}")
|
|
244
|
+
raise CommonError(f"{CommonError.AZURE_CREDENTIAL_ERROR}: {str(e)}")
|
|
245
|
+
except Exception as e:
|
|
246
|
+
logger.error(f"Unexpected error creating Azure credential: {str(e)}")
|
|
247
|
+
raise CommonError(
|
|
248
|
+
f"{CommonError.CREDENTIALS_PARSE_ERROR}: Unexpected error - {str(e)}"
|
|
249
|
+
)
|
|
250
|
+
|
|
251
|
+
async def validate_credential(self, credential: TokenCredential) -> bool:
|
|
252
|
+
"""
|
|
253
|
+
Validate Azure credential by attempting to get a token.
|
|
254
|
+
|
|
255
|
+
Args:
|
|
256
|
+
credential (TokenCredential): Azure credential to validate.
|
|
257
|
+
|
|
258
|
+
Returns:
|
|
259
|
+
bool: True if credential is valid, False otherwise.
|
|
260
|
+
"""
|
|
261
|
+
try:
|
|
262
|
+
logger.debug("Validating Azure credential")
|
|
263
|
+
|
|
264
|
+
# Try to get a token for Azure Management API
|
|
265
|
+
token = await run_sync(credential.get_token)(AZURE_MANAGEMENT_API_ENDPOINT)
|
|
266
|
+
|
|
267
|
+
if token and hasattr(token, "token"):
|
|
268
|
+
logger.debug("Azure credential validation successful")
|
|
269
|
+
return True
|
|
270
|
+
else:
|
|
271
|
+
logger.warning("Azure credential validation failed: No token received")
|
|
272
|
+
return False
|
|
273
|
+
|
|
274
|
+
except ClientAuthenticationError as e:
|
|
275
|
+
logger.error(
|
|
276
|
+
f"Azure credential validation failed - authentication error: {str(e)}"
|
|
277
|
+
)
|
|
278
|
+
return False
|
|
279
|
+
except ValueError as e:
|
|
280
|
+
logger.error(
|
|
281
|
+
f"Azure credential validation failed - invalid parameters: {str(e)}"
|
|
282
|
+
)
|
|
283
|
+
return False
|
|
284
|
+
except Exception as e:
|
|
285
|
+
logger.error(
|
|
286
|
+
f"Azure credential validation failed - unexpected error: {str(e)}"
|
|
287
|
+
)
|
|
288
|
+
return False
|
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Azure client implementation for the application-sdk framework.
|
|
3
|
+
|
|
4
|
+
This module provides the main AzureClient class that serves as a unified interface
|
|
5
|
+
for connecting to and interacting with Azure Storage services. It supports Service Principal
|
|
6
|
+
authentication and provides service-specific subclients.
|
|
7
|
+
|
|
8
|
+
Example:
|
|
9
|
+
>>> from application_sdk.clients.azure.client import AzureClient
|
|
10
|
+
>>> from application_sdk.clients.azure.auth import AzureAuthProvider
|
|
11
|
+
>>>
|
|
12
|
+
>>> # Create Azure client with Service Principal credentials
|
|
13
|
+
>>> credentials = {
|
|
14
|
+
... "tenant_id": "your-tenant-id",
|
|
15
|
+
... "client_id": "your-client-id",
|
|
16
|
+
... "client_secret": "your-client-secret"
|
|
17
|
+
... }
|
|
18
|
+
>>>
|
|
19
|
+
>>> client = AzureClient(credentials)
|
|
20
|
+
>>> await client.load()
|
|
21
|
+
>>>
|
|
22
|
+
>>> # Check client health
|
|
23
|
+
>>> health_status = await client.health_check()
|
|
24
|
+
>>> print(f"Overall health: {health_status.overall_health}")
|
|
25
|
+
>>> print(f"Connection health: {health_status.connection_health}")
|
|
26
|
+
>>>
|
|
27
|
+
>>> # Access health status details
|
|
28
|
+
>>> for service_name, service_health in health_status.services.items():
|
|
29
|
+
... print(f"{service_name}: {service_health.status}")
|
|
30
|
+
... if service_health.error:
|
|
31
|
+
... print(f" Error: {service_health.error}")
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
import asyncio
|
|
35
|
+
from concurrent.futures import ThreadPoolExecutor
|
|
36
|
+
from typing import Any, Dict, Optional
|
|
37
|
+
|
|
38
|
+
from azure.core.credentials import TokenCredential
|
|
39
|
+
from azure.core.exceptions import AzureError, ClientAuthenticationError
|
|
40
|
+
from pydantic import BaseModel
|
|
41
|
+
|
|
42
|
+
from application_sdk.clients import ClientInterface
|
|
43
|
+
from application_sdk.clients.azure import AZURE_MANAGEMENT_API_ENDPOINT
|
|
44
|
+
from application_sdk.clients.azure.auth import AzureAuthProvider
|
|
45
|
+
from application_sdk.common.error_codes import ClientError
|
|
46
|
+
from application_sdk.common.utils import run_sync
|
|
47
|
+
from application_sdk.observability.logger_adaptor import get_logger
|
|
48
|
+
|
|
49
|
+
logger = get_logger(__name__)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class ServiceHealth(BaseModel):
|
|
53
|
+
"""Model for individual service health status.
|
|
54
|
+
|
|
55
|
+
Attributes:
|
|
56
|
+
status: The health status of the service (e.g., "healthy", "error", "unknown")
|
|
57
|
+
error: Optional error message if the service is unhealthy
|
|
58
|
+
"""
|
|
59
|
+
|
|
60
|
+
status: str
|
|
61
|
+
error: Optional[str] = None
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class HealthStatus(BaseModel):
|
|
65
|
+
"""Model for overall Azure client health status.
|
|
66
|
+
|
|
67
|
+
Attributes:
|
|
68
|
+
connection_health: Whether the Azure connection is healthy
|
|
69
|
+
services: Dictionary mapping service names to their health status
|
|
70
|
+
overall_health: Overall health status considering connection and services
|
|
71
|
+
"""
|
|
72
|
+
|
|
73
|
+
connection_health: bool
|
|
74
|
+
services: Dict[str, ServiceHealth]
|
|
75
|
+
overall_health: bool
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
class AzureClient(ClientInterface):
|
|
79
|
+
"""
|
|
80
|
+
Main Azure client for the application-sdk framework.
|
|
81
|
+
|
|
82
|
+
This client provides a unified interface for connecting to and interacting
|
|
83
|
+
with Azure services. It supports Service Principal authentication
|
|
84
|
+
and provides service-specific subclients for different Azure services.
|
|
85
|
+
|
|
86
|
+
Attributes:
|
|
87
|
+
credentials (Dict[str, Any]): Azure connection credentials
|
|
88
|
+
resolved_credentials (Dict[str, Any]): Resolved credentials after processing
|
|
89
|
+
credential (DefaultAzureCredential): Azure credential instance
|
|
90
|
+
auth_provider (AzureAuthProvider): Authentication provider instance
|
|
91
|
+
_services (Dict[str, Any]): Cache of service clients
|
|
92
|
+
_executor (ThreadPoolExecutor): Thread pool for async operations
|
|
93
|
+
_connection_health (bool): Connection health status
|
|
94
|
+
"""
|
|
95
|
+
|
|
96
|
+
def __init__(
|
|
97
|
+
self,
|
|
98
|
+
credentials: Optional[Dict[str, Any]] = None,
|
|
99
|
+
max_workers: int = 10,
|
|
100
|
+
**kwargs: Any,
|
|
101
|
+
):
|
|
102
|
+
"""
|
|
103
|
+
Initialize the Azure client.
|
|
104
|
+
|
|
105
|
+
Args:
|
|
106
|
+
credentials (Optional[Dict[str, Any]]): Azure Service Principal credentials.
|
|
107
|
+
Must include tenant_id, client_id, and client_secret.
|
|
108
|
+
max_workers (int): Maximum number of worker threads for async operations.
|
|
109
|
+
**kwargs: Additional keyword arguments passed to service clients.
|
|
110
|
+
"""
|
|
111
|
+
self.credentials = credentials or {}
|
|
112
|
+
self.resolved_credentials: Dict[str, Any] = {}
|
|
113
|
+
self.credential: Optional[TokenCredential] = None
|
|
114
|
+
self.auth_provider = AzureAuthProvider()
|
|
115
|
+
self._services: Dict[str, Any] = {}
|
|
116
|
+
self._executor = ThreadPoolExecutor(max_workers=max_workers)
|
|
117
|
+
self._connection_health = False
|
|
118
|
+
self._kwargs = kwargs
|
|
119
|
+
|
|
120
|
+
async def load(self, credentials: Optional[Dict[str, Any]] = None) -> None:
|
|
121
|
+
"""
|
|
122
|
+
Load and establish Azure connection using Service Principal authentication.
|
|
123
|
+
|
|
124
|
+
Args:
|
|
125
|
+
credentials (Optional[Dict[str, Any]]): Azure Service Principal credentials.
|
|
126
|
+
If provided, will override the credentials passed to __init__.
|
|
127
|
+
Must include tenant_id, client_id, and client_secret.
|
|
128
|
+
|
|
129
|
+
Raises:
|
|
130
|
+
ClientError: If connection fails due to authentication or connection issues
|
|
131
|
+
"""
|
|
132
|
+
if credentials:
|
|
133
|
+
self.credentials = credentials
|
|
134
|
+
|
|
135
|
+
try:
|
|
136
|
+
logger.info("Loading Azure client...")
|
|
137
|
+
|
|
138
|
+
# Handle credential resolution
|
|
139
|
+
if "credential_guid" in self.credentials:
|
|
140
|
+
# If we have a credential_guid, use the async get_credentials function
|
|
141
|
+
from application_sdk.services.secretstore import SecretStore
|
|
142
|
+
|
|
143
|
+
self.resolved_credentials = await SecretStore.get_credentials(
|
|
144
|
+
self.credentials["credential_guid"]
|
|
145
|
+
)
|
|
146
|
+
else:
|
|
147
|
+
# If credentials are already resolved (direct format), use them as-is
|
|
148
|
+
# Check if credentials appear to need resolution but no credential_guid provided
|
|
149
|
+
if (
|
|
150
|
+
"secret-path" in self.credentials
|
|
151
|
+
or "credentialSource" in self.credentials
|
|
152
|
+
):
|
|
153
|
+
logger.warning(
|
|
154
|
+
"Credentials appear to need resolution but no credential_guid provided. Using as-is."
|
|
155
|
+
)
|
|
156
|
+
# Credentials are already in the correct format
|
|
157
|
+
self.resolved_credentials = self.credentials
|
|
158
|
+
|
|
159
|
+
# Create Azure credential using Service Principal authentication
|
|
160
|
+
self.credential = await self.auth_provider.create_credential(
|
|
161
|
+
auth_type="service_principal", credentials=self.resolved_credentials
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
# Test the connection
|
|
165
|
+
await self._test_connection()
|
|
166
|
+
|
|
167
|
+
self._connection_health = True
|
|
168
|
+
logger.info("Azure client loaded successfully")
|
|
169
|
+
|
|
170
|
+
except ClientAuthenticationError as e:
|
|
171
|
+
logger.error(f"Azure authentication failed: {str(e)}")
|
|
172
|
+
raise ClientError(f"{ClientError.CLIENT_AUTH_ERROR}: {str(e)}")
|
|
173
|
+
except AzureError as e:
|
|
174
|
+
logger.error(f"Azure connection error: {str(e)}")
|
|
175
|
+
raise ClientError(f"{ClientError.CLIENT_AUTH_ERROR}: {str(e)}")
|
|
176
|
+
except ValueError as e:
|
|
177
|
+
logger.error(f"Invalid Azure client parameters: {str(e)}")
|
|
178
|
+
raise ClientError(
|
|
179
|
+
f"{ClientError.INPUT_VALIDATION_ERROR}: Invalid parameters - {str(e)}"
|
|
180
|
+
)
|
|
181
|
+
except TypeError as e:
|
|
182
|
+
logger.error(f"Wrong Azure client parameter types: {str(e)}")
|
|
183
|
+
raise ClientError(
|
|
184
|
+
f"{ClientError.INPUT_VALIDATION_ERROR}: Invalid parameter types - {str(e)}"
|
|
185
|
+
)
|
|
186
|
+
except Exception as e:
|
|
187
|
+
logger.error(f"Unexpected error loading Azure client: {str(e)}")
|
|
188
|
+
raise ClientError(
|
|
189
|
+
f"{ClientError.CLIENT_AUTH_ERROR}: Unexpected error - {str(e)}"
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
async def close(self) -> None:
|
|
193
|
+
"""Close Azure connections and clean up resources."""
|
|
194
|
+
try:
|
|
195
|
+
logger.info("Closing Azure client...")
|
|
196
|
+
|
|
197
|
+
# Close all service clients
|
|
198
|
+
for service_name, service_client in self._services.items():
|
|
199
|
+
try:
|
|
200
|
+
if hasattr(service_client, "close"):
|
|
201
|
+
await service_client.close()
|
|
202
|
+
elif hasattr(service_client, "disconnect"):
|
|
203
|
+
await service_client.disconnect()
|
|
204
|
+
except Exception as e:
|
|
205
|
+
logger.warning(f"Error closing {service_name} client: {str(e)}")
|
|
206
|
+
|
|
207
|
+
# Clear service cache
|
|
208
|
+
self._services.clear()
|
|
209
|
+
|
|
210
|
+
# Shutdown executor
|
|
211
|
+
self._executor.shutdown(wait=True)
|
|
212
|
+
|
|
213
|
+
# Reset connection health
|
|
214
|
+
self._connection_health = False
|
|
215
|
+
|
|
216
|
+
logger.info("Azure client closed successfully")
|
|
217
|
+
|
|
218
|
+
except Exception as e:
|
|
219
|
+
logger.error(f"Error closing Azure client: {str(e)}")
|
|
220
|
+
|
|
221
|
+
async def health_check(self) -> HealthStatus:
|
|
222
|
+
"""
|
|
223
|
+
Perform health check on Azure connection and services.
|
|
224
|
+
|
|
225
|
+
Returns:
|
|
226
|
+
HealthStatus: Health status information.
|
|
227
|
+
"""
|
|
228
|
+
health_status = HealthStatus(
|
|
229
|
+
connection_health=self._connection_health,
|
|
230
|
+
services={},
|
|
231
|
+
overall_health=False,
|
|
232
|
+
)
|
|
233
|
+
|
|
234
|
+
if not self._connection_health:
|
|
235
|
+
return health_status
|
|
236
|
+
|
|
237
|
+
# Check each service
|
|
238
|
+
for service_name, service_client in self._services.items():
|
|
239
|
+
try:
|
|
240
|
+
if hasattr(service_client, "health_check"):
|
|
241
|
+
service_health = await service_client.health_check()
|
|
242
|
+
# Handle different return types from service health checks
|
|
243
|
+
if isinstance(service_health, dict):
|
|
244
|
+
status = service_health.get("status", "unknown")
|
|
245
|
+
error = service_health.get("error")
|
|
246
|
+
elif hasattr(service_health, "status"):
|
|
247
|
+
# Handle Pydantic models or objects with status attribute
|
|
248
|
+
status = getattr(service_health, "status", "unknown")
|
|
249
|
+
error = getattr(service_health, "error", None)
|
|
250
|
+
else:
|
|
251
|
+
# Fallback for unexpected return types
|
|
252
|
+
status = "unknown"
|
|
253
|
+
error = f"Unexpected health check return type: {type(service_health)}"
|
|
254
|
+
else:
|
|
255
|
+
status = "unknown"
|
|
256
|
+
error = None
|
|
257
|
+
|
|
258
|
+
health_status.services[service_name] = ServiceHealth(
|
|
259
|
+
status=status,
|
|
260
|
+
error=error,
|
|
261
|
+
)
|
|
262
|
+
except Exception as e:
|
|
263
|
+
health_status.services[service_name] = ServiceHealth(
|
|
264
|
+
status="error", error=str(e)
|
|
265
|
+
)
|
|
266
|
+
|
|
267
|
+
# Overall health is True if connection is healthy and at least one service is available
|
|
268
|
+
health_status.overall_health = (
|
|
269
|
+
self._connection_health and len(health_status.services) > 0
|
|
270
|
+
)
|
|
271
|
+
|
|
272
|
+
return health_status
|
|
273
|
+
|
|
274
|
+
async def _test_connection(self) -> None:
|
|
275
|
+
"""
|
|
276
|
+
Test the Azure connection by attempting to get a token.
|
|
277
|
+
|
|
278
|
+
Raises:
|
|
279
|
+
ClientAuthenticationError: If connection test fails.
|
|
280
|
+
"""
|
|
281
|
+
if not self.credential:
|
|
282
|
+
raise ClientError(
|
|
283
|
+
f"{ClientError.AUTH_CREDENTIALS_ERROR}: No credential available for connection test"
|
|
284
|
+
)
|
|
285
|
+
|
|
286
|
+
try:
|
|
287
|
+
# Test the credential by getting a token
|
|
288
|
+
await run_sync(self.credential.get_token)(AZURE_MANAGEMENT_API_ENDPOINT)
|
|
289
|
+
except ClientAuthenticationError as e:
|
|
290
|
+
logger.error(
|
|
291
|
+
f"Azure connection test failed - authentication error: {str(e)}"
|
|
292
|
+
)
|
|
293
|
+
raise ClientError(f"{ClientError.CLIENT_AUTH_ERROR}: {str(e)}")
|
|
294
|
+
except AzureError as e:
|
|
295
|
+
logger.error(f"Azure connection test failed - service error: {str(e)}")
|
|
296
|
+
raise ClientError(f"{ClientError.CLIENT_AUTH_ERROR}: {str(e)}")
|
|
297
|
+
except ValueError as e:
|
|
298
|
+
logger.error(f"Azure connection test failed - invalid parameters: {str(e)}")
|
|
299
|
+
raise ClientError(
|
|
300
|
+
f"{ClientError.INPUT_VALIDATION_ERROR}: Invalid parameters - {str(e)}"
|
|
301
|
+
)
|
|
302
|
+
except Exception as e:
|
|
303
|
+
logger.error(f"Azure connection test failed - unexpected error: {str(e)}")
|
|
304
|
+
raise ClientError(
|
|
305
|
+
f"{ClientError.CLIENT_AUTH_ERROR}: Unexpected error - {str(e)}"
|
|
306
|
+
)
|
|
307
|
+
|
|
308
|
+
def __enter__(self):
|
|
309
|
+
"""Context manager entry."""
|
|
310
|
+
return self
|
|
311
|
+
|
|
312
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
313
|
+
"""Context manager exit."""
|
|
314
|
+
# Note: This is a synchronous context manager.
|
|
315
|
+
# For proper async cleanup, use the async context manager instead.
|
|
316
|
+
# This method is kept for backward compatibility but doesn't guarantee cleanup.
|
|
317
|
+
logger.warning(
|
|
318
|
+
"Using synchronous context manager. For proper async cleanup, "
|
|
319
|
+
"use 'async with AzureClient() as client:' instead."
|
|
320
|
+
)
|
|
321
|
+
# Schedule cleanup but don't wait for it
|
|
322
|
+
try:
|
|
323
|
+
loop = asyncio.get_event_loop()
|
|
324
|
+
if loop.is_running():
|
|
325
|
+
loop.create_task(self.close())
|
|
326
|
+
except RuntimeError:
|
|
327
|
+
# No event loop running, can't schedule async cleanup
|
|
328
|
+
logger.warning("No event loop running, async cleanup not possible")
|
|
329
|
+
|
|
330
|
+
async def __aenter__(self):
|
|
331
|
+
"""Async context manager entry."""
|
|
332
|
+
return self
|
|
333
|
+
|
|
334
|
+
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
|
335
|
+
"""Async context manager exit."""
|
|
336
|
+
await self.close()
|