atlan-application-sdk 0.1.1rc35__tar.gz → 0.1.1rc37__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-0.1.1rc37/.github/release_notes.md +7 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/CHANGELOG.md +20 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/PKG-INFO +4 -2
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/activities/common/models.py +2 -1
- atlan_application_sdk-0.1.1rc37/application_sdk/activities/lock_management.py +110 -0
- atlan_application_sdk-0.1.1rc37/application_sdk/clients/redis.py +443 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/clients/temporal.py +31 -187
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/common/error_codes.py +24 -3
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/constants.py +18 -1
- atlan_application_sdk-0.1.1rc37/application_sdk/decorators/locks.py +42 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/handlers/base.py +18 -1
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/inputs/parquet.py +4 -4
- atlan_application_sdk-0.1.1rc37/application_sdk/interceptors/events.py +193 -0
- atlan_application_sdk-0.1.1rc37/application_sdk/interceptors/lock.py +139 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/outputs/__init__.py +24 -1
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/outputs/json.py +57 -38
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/outputs/parquet.py +116 -18
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/version.py +1 -1
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/workflows/metadata_extraction/sql.py +18 -5
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/pyproject.toml +6 -2
- atlan_application_sdk-0.1.1rc37/tests/unit/activities/test_lock_management.py +132 -0
- atlan_application_sdk-0.1.1rc37/tests/unit/clients/test_redis_client.py +343 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/clients/test_temporal_client.py +2 -1
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/inputs/test_parquet.py +4 -1
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/outputs/test_output.py +12 -3
- atlan_application_sdk-0.1.1rc37/tests/unit/transformers/__init__.py +0 -0
- atlan_application_sdk-0.1.1rc37/tests/unit/transformers/atlas/__init__.py +0 -0
- atlan_application_sdk-0.1.1rc35/tests/unit/workflows/metadata_extraction/test_sql.py → atlan_application_sdk-0.1.1rc37/tests/unit/workflows/metadata_extraction/test_sql_workflow.py +17 -14
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/uv.lock +89 -6
- atlan_application_sdk-0.1.1rc35/.github/release_notes.md +0 -7
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.cursor/BUGBOT.md +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.cursor/rules/documentation.mdc +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.cursor/rules/exception-handling.mdc +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.cursor/rules/guidelines.mdc +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.cursor/rules/logging.mdc +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.cursor/rules/performance.mdc +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.cursor/rules/setup.mdc +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.cursor/rules/standards.mdc +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.cursor/rules/testing.mdc +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.env.example +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/CODEOWNERS +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/ISSUE_TEMPLATE/bug_report.yaml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/ISSUE_TEMPLATE/config.yaml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/ISSUE_TEMPLATE/feature_request.yaml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/actions/docgen/action.yaml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/actions/doclint/action.yaml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/actions/docstring-coverage/action.yaml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/actions/e2e-apps/action.yaml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/actions/e2e-examples/action.yaml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/actions/setup-deps/action.yaml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/actions/sync-branches/action.yaml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/actions/trivy/action.yaml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/actions/trivy-container/action.yaml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/actions/unit-tests/action.yaml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/dependabot.yaml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/pull_request_template.md +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/scripts/extract_release_notes.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/scripts/pre_release.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/scripts/release.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/scripts/trivy-to-markdown.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/scripts/update_changelog.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/styles/Microsoft/AMPM.yml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/styles/Microsoft/Accessibility.yml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/styles/Microsoft/Acronyms.yml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/styles/Microsoft/Adverbs.yml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/styles/Microsoft/Auto.yml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/styles/Microsoft/Avoid.yml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/styles/Microsoft/Contractions.yml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/styles/Microsoft/Dashes.yml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/styles/Microsoft/DateFormat.yml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/styles/Microsoft/DateNumbers.yml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/styles/Microsoft/DateOrder.yml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/styles/Microsoft/Ellipses.yml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/styles/Microsoft/FirstPerson.yml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/styles/Microsoft/Foreign.yml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/styles/Microsoft/Gender.yml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/styles/Microsoft/GenderBias.yml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/styles/Microsoft/GeneralURL.yml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/styles/Microsoft/HeadingAcronyms.yml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/styles/Microsoft/HeadingColons.yml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/styles/Microsoft/HeadingPunctuation.yml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/styles/Microsoft/Headings.yml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/styles/Microsoft/Hyphens.yml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/styles/Microsoft/Negative.yml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/styles/Microsoft/Ordinal.yml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/styles/Microsoft/OxfordComma.yml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/styles/Microsoft/Passive.yml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/styles/Microsoft/Percentages.yml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/styles/Microsoft/Plurals.yml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/styles/Microsoft/Quotes.yml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/styles/Microsoft/RangeTime.yml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/styles/Microsoft/Semicolon.yml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/styles/Microsoft/SentenceLength.yml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/styles/Microsoft/Spacing.yml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/styles/Microsoft/Suspended.yml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/styles/Microsoft/Terms.yml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/styles/Microsoft/URLFormat.yml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/styles/Microsoft/Units.yml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/styles/Microsoft/Vocab.yml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/styles/Microsoft/We.yml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/styles/Microsoft/Wordiness.yml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/styles/Microsoft/meta.json +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/styles/config/vocabularies/deviations/accept.txt +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/styles/config/vocabularies/deviations/reject.txt +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/workflow-templates/checks.properties.json +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/workflow-templates/checks.yaml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/workflow-templates/codeql.properties.json +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/workflow-templates/codeql.yaml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/workflow-templates/dependency-review.properties.json +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/workflow-templates/dependency-review.yml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/workflow-templates/stale.properties.json +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/workflow-templates/stale.yml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/workflow-templates/trivy-container.properties.json +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/workflow-templates/trivy-container.yaml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/workflow-templates/trivy.properties.json +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/workflow-templates/trivy.yaml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/workflows/codeql.yaml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/workflows/pre-release.yaml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/workflows/pull_request.yaml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/workflows/push.yaml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/workflows/release.yaml.disabled +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/workflows/scale-tests.yaml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/workflows/schedule.yaml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/workflows/tag-and-publish.yaml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/workflows/trivy-container.yaml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.github/workflows/verify-snyk-status.yml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.gitignore +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.pre-commit-config.yaml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/.vscode/launch.json +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/CODE_OF_CONDUCT.md +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/CONTRIBUTING.md +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/LICENSE +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/NOTICE +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/README.md +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/SECURITY.md +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/activities/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/activities/common/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/activities/common/utils.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/activities/metadata_extraction/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/activities/metadata_extraction/base.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/activities/metadata_extraction/rest.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/activities/metadata_extraction/sql.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/activities/query_extraction/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/activities/query_extraction/sql.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/application/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/application/metadata_extraction/sql.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/clients/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/clients/async_atlan.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/clients/atlan.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/clients/atlan_auth.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/clients/base.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/clients/sql.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/clients/utils.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/clients/workflow.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/common/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/common/aws_utils.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/common/dapr_utils.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/common/dataframe_utils.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/common/utils.py +0 -0
- {atlan_application_sdk-0.1.1rc35/application_sdk/docgen/exporters → atlan_application_sdk-0.1.1rc37/application_sdk/decorators}/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/docgen/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35/application_sdk/docgen/models → atlan_application_sdk-0.1.1rc37/application_sdk/docgen/exporters}/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/docgen/exporters/mkdocs.py +0 -0
- {atlan_application_sdk-0.1.1rc35/application_sdk/docgen/models/export → atlan_application_sdk-0.1.1rc37/application_sdk/docgen/models}/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35/application_sdk/docgen/parsers → atlan_application_sdk-0.1.1rc37/application_sdk/docgen/models/export}/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/docgen/models/export/page.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/docgen/models/manifest/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/docgen/models/manifest/customer.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/docgen/models/manifest/internal.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/docgen/models/manifest/metadata.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/docgen/models/manifest/page.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/docgen/models/manifest/section.py +0 -0
- {atlan_application_sdk-0.1.1rc35/application_sdk/observability → atlan_application_sdk-0.1.1rc37/application_sdk/docgen/parsers}/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/docgen/parsers/directory.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/docgen/parsers/manifest.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/events/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/events/models.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/handlers/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/handlers/sql.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/inputs/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/inputs/iceberg.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/inputs/json.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/inputs/sql_query.py +0 -0
- {atlan_application_sdk-0.1.1rc35/application_sdk/server/fastapi/routers → atlan_application_sdk-0.1.1rc37/application_sdk/interceptors}/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35/application_sdk/test_utils → atlan_application_sdk-0.1.1rc37/application_sdk/observability}/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/observability/decorators/observability_decorator.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/observability/logger_adaptor.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/observability/metrics_adaptor.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/observability/observability.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/observability/traces_adaptor.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/observability/utils.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/outputs/iceberg.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/server/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/server/fastapi/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/server/fastapi/middleware/logmiddleware.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/server/fastapi/middleware/metrics.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/server/fastapi/models.py +0 -0
- {atlan_application_sdk-0.1.1rc35/application_sdk/test_utils/hypothesis → atlan_application_sdk-0.1.1rc37/application_sdk/server/fastapi/routers}/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/server/fastapi/routers/server.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/server/fastapi/utils.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/services/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/services/atlan_storage.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/services/eventstore.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/services/objectstore.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/services/secretstore.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/services/statestore.py +0 -0
- {atlan_application_sdk-0.1.1rc35/application_sdk/test_utils/hypothesis/strategies → atlan_application_sdk-0.1.1rc37/application_sdk/test_utils}/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/test_utils/e2e/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/test_utils/e2e/base.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/test_utils/e2e/client.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/test_utils/e2e/conftest.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/test_utils/e2e/utils.py +0 -0
- {atlan_application_sdk-0.1.1rc35/application_sdk/test_utils/hypothesis/strategies/clients → atlan_application_sdk-0.1.1rc37/application_sdk/test_utils/hypothesis}/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35/application_sdk/test_utils/hypothesis/strategies/common → atlan_application_sdk-0.1.1rc37/application_sdk/test_utils/hypothesis/strategies}/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35/application_sdk/test_utils/hypothesis/strategies/handlers → atlan_application_sdk-0.1.1rc37/application_sdk/test_utils/hypothesis/strategies/clients}/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/test_utils/hypothesis/strategies/clients/sql.py +0 -0
- {atlan_application_sdk-0.1.1rc35/application_sdk/test_utils/hypothesis/strategies/handlers/sql → atlan_application_sdk-0.1.1rc37/application_sdk/test_utils/hypothesis/strategies/common}/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/test_utils/hypothesis/strategies/common/logger.py +0 -0
- {atlan_application_sdk-0.1.1rc35/application_sdk/test_utils/hypothesis/strategies/inputs → atlan_application_sdk-0.1.1rc37/application_sdk/test_utils/hypothesis/strategies/handlers}/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35/application_sdk/test_utils/hypothesis/strategies/outputs → atlan_application_sdk-0.1.1rc37/application_sdk/test_utils/hypothesis/strategies/handlers/sql}/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/test_utils/hypothesis/strategies/handlers/sql/sql_metadata.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/test_utils/hypothesis/strategies/handlers/sql/sql_preflight.py +0 -0
- {atlan_application_sdk-0.1.1rc35/application_sdk/test_utils/hypothesis/strategies/server → atlan_application_sdk-0.1.1rc37/application_sdk/test_utils/hypothesis/strategies/inputs}/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/test_utils/hypothesis/strategies/inputs/json_input.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/test_utils/hypothesis/strategies/inputs/parquet_input.py +0 -0
- {atlan_application_sdk-0.1.1rc35/application_sdk/test_utils/scale_data_generator → atlan_application_sdk-0.1.1rc37/application_sdk/test_utils/hypothesis/strategies/outputs}/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/test_utils/hypothesis/strategies/outputs/json_output.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/test_utils/hypothesis/strategies/outputs/statestore.py +0 -0
- {atlan_application_sdk-0.1.1rc35/application_sdk/test_utils/scale_data_generator/output_handler → atlan_application_sdk-0.1.1rc37/application_sdk/test_utils/hypothesis/strategies/server}/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/test_utils/hypothesis/strategies/server/fastapi/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/test_utils/hypothesis/strategies/sql_client.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/test_utils/hypothesis/strategies/temporal.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/test_utils/scale_data_generator/README.md +0 -0
- {atlan_application_sdk-0.1.1rc35/application_sdk/transformers/common → atlan_application_sdk-0.1.1rc37/application_sdk/test_utils/scale_data_generator}/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/test_utils/scale_data_generator/config_loader.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/test_utils/scale_data_generator/data_generator.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/test_utils/scale_data_generator/driver.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/test_utils/scale_data_generator/examples/config.yaml +0 -0
- {atlan_application_sdk-0.1.1rc35/tests → atlan_application_sdk-0.1.1rc37/application_sdk/test_utils/scale_data_generator/output_handler}/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/test_utils/scale_data_generator/output_handler/base.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/test_utils/scale_data_generator/output_handler/csv_handler.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/test_utils/scale_data_generator/output_handler/json_handler.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/test_utils/scale_data_generator/output_handler/parquet_handler.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/test_utils/workflow_monitoring.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/transformers/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/transformers/atlas/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/transformers/atlas/sql.py +0 -0
- {atlan_application_sdk-0.1.1rc35/tests/unit → atlan_application_sdk-0.1.1rc37/application_sdk/transformers/common}/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/transformers/common/utils.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/transformers/query/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/transformers/query/templates/column.yaml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/transformers/query/templates/database.yaml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/transformers/query/templates/extras-procedure.yaml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/transformers/query/templates/function.yaml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/transformers/query/templates/schema.yaml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/transformers/query/templates/table.yaml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/transformers/query/templates/tag_attachment.yaml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/worker.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/workflows/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/workflows/metadata_extraction/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/workflows/query_extraction/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/application_sdk/workflows/query_extraction/sql.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/components/README.md +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/components/atlan-storage.yaml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/components/aws-secrets.yaml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/components/deployment-secrets.yaml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/components/eventstore.yaml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/components/objectstore.yaml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/components/secretstore.yaml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/components/statestore.yaml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/docs/docs/concepts/activities.md +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/docs/docs/concepts/application.md +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/docs/docs/concepts/application_sql.md +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/docs/docs/concepts/atlanupload.md +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/docs/docs/concepts/clients.md +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/docs/docs/concepts/common.md +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/docs/docs/concepts/handlers.md +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/docs/docs/concepts/inputs.md +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/docs/docs/concepts/output_paths.md +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/docs/docs/concepts/outputs.md +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/docs/docs/concepts/server.md +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/docs/docs/concepts/services.md +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/docs/docs/concepts/temporal_auth.md +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/docs/docs/concepts/worker.md +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/docs/docs/concepts/workflows.md +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/docs/docs/configuration.md +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/docs/docs/guides/architecture.md +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/docs/docs/guides/atlantis.md +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/docs/docs/guides/best-practices.md +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/docs/docs/guides/getting-started.md +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/docs/docs/guides/index.md +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/docs/docs/guides/partners.md +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/docs/docs/guides/secretstores.md +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/docs/docs/guides/sql-application-guide.md +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/docs/docs/guides/test-framework.md +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/docs/docs/index.md +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/docs/docs/setup/LINUX.md +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/docs/docs/setup/MAC.md +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/docs/docs/setup/WINDOWS.md +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/docs/docs/setup/troubleshooting.md +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/docs/docs/static/assets/logo.svg +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/docs/docs/static/images/phoenix-sdk-featureset.png +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/docs/docs/static/javascripts/mathjax.js +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/docs/docs/static/stylesheets/extra.css +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/docs/mkdocs.yml +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/examples/README.md +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/examples/application_custom_fastapi.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/examples/application_fastapi.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/examples/application_hello_world.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/examples/application_sql.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/examples/application_sql_miner.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/examples/application_sql_with_custom_pyatlan_transformer.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/examples/application_sql_with_custom_transformer.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/examples/run_examples.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/examples/sql_query_templates/database.yaml +0 -0
- {atlan_application_sdk-0.1.1rc35/tests/unit/activities → atlan_application_sdk-0.1.1rc37/tests}/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/conftest.py +0 -0
- {atlan_application_sdk-0.1.1rc35/tests/unit/activities/common → atlan_application_sdk-0.1.1rc37/tests/unit}/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35/tests/unit/activities/metadata_extraction → atlan_application_sdk-0.1.1rc37/tests/unit/activities}/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35/tests/unit/activities/query_extraction → atlan_application_sdk-0.1.1rc37/tests/unit/activities/common}/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/activities/common/test_utils.py +0 -0
- {atlan_application_sdk-0.1.1rc35/tests/unit/application → atlan_application_sdk-0.1.1rc37/tests/unit/activities/metadata_extraction}/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/activities/metadata_extraction/test_sql.py +0 -0
- {atlan_application_sdk-0.1.1rc35/tests/unit/clients → atlan_application_sdk-0.1.1rc37/tests/unit/activities/query_extraction}/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/activities/test_activities.py +0 -0
- {atlan_application_sdk-0.1.1rc35/tests/unit/handlers → atlan_application_sdk-0.1.1rc37/tests/unit/application}/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/application/metadata_extraction/test_sql.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/application/test_application.py +0 -0
- {atlan_application_sdk-0.1.1rc35/tests/unit/observability → atlan_application_sdk-0.1.1rc37/tests/unit/clients}/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/clients/test_async_atlan.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/clients/test_async_sql_client.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/clients/test_atlan_auth.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/clients/test_atlan_client.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/clients/test_atlanauth.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/clients/test_base_client.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/clients/test_sql_client.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/common/test_aws_utils.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/common/test_credential_utils.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/common/test_utils.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/docgen/parsers/test_directory_parser.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/docgen/parsers/test_manifest_parser.py +0 -0
- {atlan_application_sdk-0.1.1rc35/tests/unit/server → atlan_application_sdk-0.1.1rc37/tests/unit/handlers}/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/handlers/sql/test_auth.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/handlers/sql/test_check_schemas_and_databases.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/handlers/sql/test_extract_allowed_schemas.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/handlers/sql/test_metadata.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/handlers/sql/test_preflight_check.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/handlers/sql/test_prepare_metadata.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/handlers/sql/test_tables_check.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/handlers/sql/test_validate_filters.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/handlers/test_base_handler.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/inputs/test_json.py +0 -0
- {atlan_application_sdk-0.1.1rc35/tests/unit/server/fastapi/routers → atlan_application_sdk-0.1.1rc37/tests/unit/observability}/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/observability/test_logger_adaptor.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/observability/test_metrics_adaptor.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/observability/test_traces_adaptor.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/outputs/test_iceberg.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/outputs/test_json_output.py +0 -0
- {atlan_application_sdk-0.1.1rc35/tests/unit/transformers → atlan_application_sdk-0.1.1rc37/tests/unit/server}/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35/tests/unit/transformers/atlas → atlan_application_sdk-0.1.1rc37/tests/unit/server/fastapi/routers}/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/server/fastapi/routers/server.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/server/fastapi/test_fastapi.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/services/test_atlan_storage.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/services/test_eventstore.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/services/test_objectstore.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/services/test_statestore.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/test_worker.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/transformers/atlas/resources/raw_columns.json +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/transformers/atlas/resources/raw_databases.json +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/transformers/atlas/resources/raw_functions.json +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/transformers/atlas/resources/raw_procedures.json +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/transformers/atlas/resources/raw_schemas.json +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/transformers/atlas/resources/raw_tables.json +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/transformers/atlas/resources/transformed_columns.json +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/transformers/atlas/resources/transformed_databases.json +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/transformers/atlas/resources/transformed_functions.json +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/transformers/atlas/resources/transformed_procedures.json +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/transformers/atlas/resources/transformed_schemas.json +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/transformers/atlas/resources/transformed_tables.json +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/transformers/atlas/test_column.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/transformers/atlas/test_database.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/transformers/atlas/test_function.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/transformers/atlas/test_procedure.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/transformers/atlas/test_schema.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/transformers/atlas/test_table.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/transformers/query/resources/raw/column.json +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/transformers/query/resources/raw/database.json +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/transformers/query/resources/raw/extras-procedure.json +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/transformers/query/resources/raw/function.json +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/transformers/query/resources/raw/schema.json +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/transformers/query/resources/raw/table.json +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/transformers/query/resources/transformed/column.json +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/transformers/query/resources/transformed/database.json +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/transformers/query/resources/transformed/extras-procedure.json +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/transformers/query/resources/transformed/function.json +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/transformers/query/resources/transformed/schema.json +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/transformers/query/resources/transformed/table.json +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/transformers/query/test_sql_transformer.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/transformers/query/test_sql_transformer_output_validation.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/workflows/query_extraction/__init__.py +0 -0
- {atlan_application_sdk-0.1.1rc35 → atlan_application_sdk-0.1.1rc37}/tests/unit/workflows/query_extraction/test_sql.py +0 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
## v0.1.1rc37 (September 03, 2025)
|
|
2
|
+
|
|
3
|
+
Full Changelog: https://github.com/atlanhq/application-sdk/compare/v0.1.1rc36...v0.1.1rc37
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
- add file size-based chunking to JsonOutput (#650) (by @Nishchith Shetty in [7e7685b](https://github.com/atlanhq/application-sdk/commit/7e7685b))
|
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v0.1.1rc37 (September 03, 2025)
|
|
4
|
+
|
|
5
|
+
Full Changelog: https://github.com/atlanhq/application-sdk/compare/v0.1.1rc36...v0.1.1rc37
|
|
6
|
+
|
|
7
|
+
### Features
|
|
8
|
+
|
|
9
|
+
- add file size-based chunking to JsonOutput (#650) (by @Nishchith Shetty in [7e7685b](https://github.com/atlanhq/application-sdk/commit/7e7685b))
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
## v0.1.1rc36 (September 01, 2025)
|
|
14
|
+
|
|
15
|
+
Full Changelog: https://github.com/atlanhq/application-sdk/compare/v0.1.1rc35...v0.1.1rc36
|
|
16
|
+
|
|
17
|
+
### Features
|
|
18
|
+
|
|
19
|
+
- Update to pyatlan 8.0.2 to get fix for AsyncWorkflowSearchResponse async iterator (#680) (by @Ernest Hill in [a33bc4c](https://github.com/atlanhq/application-sdk/commit/a33bc4c))
|
|
20
|
+
- implement Redis client with sync/async support and distributed locking (#621) (by @Mustafa in [e384ceb](https://github.com/atlanhq/application-sdk/commit/e384ceb))
|
|
21
|
+
- implement abstract methods in BaseHandler (by @Mustafa in [c7c1937](https://github.com/atlanhq/application-sdk/commit/c7c1937))
|
|
22
|
+
|
|
3
23
|
## v0.1.1rc35 (August 28, 2025)
|
|
4
24
|
|
|
5
25
|
Full Changelog: https://github.com/atlanhq/application-sdk/compare/v0.1.1rc34...v0.1.1rc35
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: atlan-application-sdk
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.1rc37
|
|
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
|
|
@@ -26,12 +26,14 @@ Requires-Dist: fastapi[standard]>=0.115.0
|
|
|
26
26
|
Requires-Dist: loguru>=0.7.3
|
|
27
27
|
Requires-Dist: opentelemetry-exporter-otlp>=1.27.0
|
|
28
28
|
Requires-Dist: psutil>=7.0.0
|
|
29
|
-
Requires-Dist: pyatlan>=8.0.
|
|
29
|
+
Requires-Dist: pyatlan>=8.0.2
|
|
30
30
|
Requires-Dist: pydantic>=2.10.6
|
|
31
31
|
Requires-Dist: python-dotenv>=1.1.0
|
|
32
32
|
Requires-Dist: uvloop>=0.21.0; sys_platform != 'win32'
|
|
33
33
|
Provides-Extra: daft
|
|
34
34
|
Requires-Dist: daft>=0.4.12; extra == 'daft'
|
|
35
|
+
Provides-Extra: distributed-lock
|
|
36
|
+
Requires-Dist: redis[hiredis]>=5.2.0; extra == 'distributed-lock'
|
|
35
37
|
Provides-Extra: iam-auth
|
|
36
38
|
Requires-Dist: boto3>=1.38.6; extra == 'iam-auth'
|
|
37
39
|
Provides-Extra: iceberg
|
|
@@ -4,7 +4,7 @@ This module contains Pydantic models used to represent various data structures
|
|
|
4
4
|
needed by activities, such as statistics and configuration.
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
-
from typing import Optional
|
|
7
|
+
from typing import List, Optional
|
|
8
8
|
|
|
9
9
|
from pydantic import BaseModel
|
|
10
10
|
|
|
@@ -34,4 +34,5 @@ class ActivityStatistics(BaseModel):
|
|
|
34
34
|
|
|
35
35
|
total_record_count: int = 0
|
|
36
36
|
chunk_count: int = 0
|
|
37
|
+
partitions: Optional[List[int]] = []
|
|
37
38
|
typename: Optional[str] = None
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"""Lock management activities for distributed locking.
|
|
2
|
+
|
|
3
|
+
These activities handle the actual Redis lock acquisition and release,
|
|
4
|
+
allowing the workflow to orchestrate locking without hitting Temporal's
|
|
5
|
+
deadlock timeout.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import asyncio
|
|
9
|
+
import random
|
|
10
|
+
from typing import Any, Dict
|
|
11
|
+
|
|
12
|
+
from temporalio import activity
|
|
13
|
+
|
|
14
|
+
from application_sdk.clients.redis import RedisClientAsync
|
|
15
|
+
from application_sdk.common.error_codes import ActivityError
|
|
16
|
+
from application_sdk.constants import APPLICATION_NAME, LOCK_RETRY_INTERVAL
|
|
17
|
+
from application_sdk.observability.logger_adaptor import get_logger
|
|
18
|
+
|
|
19
|
+
logger = get_logger(__name__)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@activity.defn
|
|
23
|
+
async def acquire_distributed_lock(
|
|
24
|
+
lock_name: str,
|
|
25
|
+
max_locks: int,
|
|
26
|
+
ttl_seconds: int = 100,
|
|
27
|
+
owner_id: str = "default_owner",
|
|
28
|
+
) -> Dict[str, Any]:
|
|
29
|
+
"""Acquire a distributed lock with retry logic.
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
lock_name (str): Name of the resource to lock.
|
|
33
|
+
max_locks (int): Maximum number of concurrent locks allowed; must be > 0.
|
|
34
|
+
ttl_seconds (int): Time-to-live for the lock in seconds.
|
|
35
|
+
owner_id (str): Unique identifier for the lock owner.
|
|
36
|
+
|
|
37
|
+
Returns:
|
|
38
|
+
dict[str, Any]: Lock information with the following keys:
|
|
39
|
+
- slot_id (int): Allocated lock slot.
|
|
40
|
+
- resource_id (str): Fully qualified lock resource ID.
|
|
41
|
+
- owner_id (str): Owner identifier.
|
|
42
|
+
|
|
43
|
+
Raises:
|
|
44
|
+
ActivityError: If lock acquisition fails due to Redis errors or invalid parameters.
|
|
45
|
+
"""
|
|
46
|
+
# Input validation
|
|
47
|
+
if max_locks <= 0:
|
|
48
|
+
raise ActivityError(
|
|
49
|
+
f"{ActivityError.LOCK_ACQUISITION_ERROR}: max_locks must be greater than 0, got {max_locks}"
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
async with RedisClientAsync() as redis_client:
|
|
53
|
+
while True:
|
|
54
|
+
slot = random.randint(0, max_locks - 1)
|
|
55
|
+
resource_id = f"{APPLICATION_NAME}:{lock_name}:{slot}"
|
|
56
|
+
|
|
57
|
+
try:
|
|
58
|
+
# Acquire lock - connection will stay open until context exits
|
|
59
|
+
acquired = await redis_client._acquire_lock(
|
|
60
|
+
resource_id, owner_id, ttl_seconds
|
|
61
|
+
)
|
|
62
|
+
if acquired:
|
|
63
|
+
logger.info(
|
|
64
|
+
f"Lock acquired for slot {slot}, resource: {resource_id}"
|
|
65
|
+
)
|
|
66
|
+
return {
|
|
67
|
+
"slot_id": slot,
|
|
68
|
+
"resource_id": resource_id,
|
|
69
|
+
"owner_id": owner_id,
|
|
70
|
+
}
|
|
71
|
+
# If not acquired, continue retrying (lock held by another owner)
|
|
72
|
+
|
|
73
|
+
except Exception as e:
|
|
74
|
+
# Redis connection or operation failed - propagate as activity error
|
|
75
|
+
logger.error(f"Redis error during lock acquisition: {e}")
|
|
76
|
+
raise ActivityError(
|
|
77
|
+
f"{ActivityError.LOCK_ACQUISITION_ERROR}: Redis error during lock acquisition for {resource_id}"
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
# Wait before retrying
|
|
81
|
+
await asyncio.sleep(LOCK_RETRY_INTERVAL)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
@activity.defn
|
|
85
|
+
async def release_distributed_lock(
|
|
86
|
+
resource_id: str, owner_id: str = "default_owner"
|
|
87
|
+
) -> bool:
|
|
88
|
+
"""Release a distributed lock.
|
|
89
|
+
|
|
90
|
+
Args:
|
|
91
|
+
resource_id: Full resource identifier for the lock
|
|
92
|
+
owner_id: Unique identifier for the lock owner
|
|
93
|
+
|
|
94
|
+
Returns:
|
|
95
|
+
True if lock was released successfully, False otherwise
|
|
96
|
+
"""
|
|
97
|
+
async with RedisClientAsync() as redis_client:
|
|
98
|
+
try:
|
|
99
|
+
released, result = await redis_client._release_lock(resource_id, owner_id)
|
|
100
|
+
if released:
|
|
101
|
+
logger.info(
|
|
102
|
+
f"Lock released successfully: {resource_id}, result: {result.value}"
|
|
103
|
+
)
|
|
104
|
+
return released
|
|
105
|
+
|
|
106
|
+
except Exception as e:
|
|
107
|
+
logger.error(f"Redis error during lock release for {resource_id}: {e}")
|
|
108
|
+
# Don't raise exception for lock release failures - log and return False
|
|
109
|
+
# Lock release is best-effort and shouldn't fail the workflow
|
|
110
|
+
return False
|
|
@@ -0,0 +1,443 @@
|
|
|
1
|
+
"""Redis client for distributed locking with high availability support."""
|
|
2
|
+
|
|
3
|
+
from enum import Enum
|
|
4
|
+
from typing import NoReturn, Union
|
|
5
|
+
|
|
6
|
+
import redis
|
|
7
|
+
import redis.asyncio as async_redis
|
|
8
|
+
from redis.exceptions import ConnectionError, RedisError, TimeoutError
|
|
9
|
+
|
|
10
|
+
from application_sdk.common.error_codes import ClientError
|
|
11
|
+
from application_sdk.constants import (
|
|
12
|
+
IS_LOCKING_DISABLED,
|
|
13
|
+
REDIS_HOST,
|
|
14
|
+
REDIS_PASSWORD,
|
|
15
|
+
REDIS_PORT,
|
|
16
|
+
REDIS_SENTINEL_HOSTS,
|
|
17
|
+
REDIS_SENTINEL_SERVICE_NAME,
|
|
18
|
+
)
|
|
19
|
+
from application_sdk.observability.logger_adaptor import get_logger
|
|
20
|
+
|
|
21
|
+
logger = get_logger(__name__)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _handle_redis_error(e: Exception) -> NoReturn:
|
|
25
|
+
"""Handle Redis errors with consistent error mapping.
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
e: The Redis exception that occurred
|
|
29
|
+
|
|
30
|
+
Raises:
|
|
31
|
+
ClientError: Appropriate ClientError based on exception type
|
|
32
|
+
"""
|
|
33
|
+
if isinstance(e, ConnectionError):
|
|
34
|
+
raise ClientError(f"{ClientError.REDIS_CONNECTION_ERROR}: {e}")
|
|
35
|
+
elif isinstance(e, TimeoutError):
|
|
36
|
+
raise ClientError(f"{ClientError.REDIS_TIMEOUT_ERROR}: {e}")
|
|
37
|
+
elif isinstance(e, RedisError):
|
|
38
|
+
raise ClientError(f"{ClientError.REDIS_PROTOCOL_ERROR}: {e}")
|
|
39
|
+
else:
|
|
40
|
+
raise ClientError(f"{ClientError.REDIS_CONNECTION_ERROR}: {e}")
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class LockReleaseResult(Enum):
|
|
44
|
+
"""Enum for lock release operation results."""
|
|
45
|
+
|
|
46
|
+
SUCCESS = "success"
|
|
47
|
+
ALREADY_RELEASED = "already_released"
|
|
48
|
+
WRONG_OWNER = "wrong_owner"
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
_LOCK_RELEASE_LUA_SCRIPT = """
|
|
52
|
+
local current_owner = redis.call("GET", KEYS[1])
|
|
53
|
+
if current_owner == false then
|
|
54
|
+
return -1 -- Key doesn't exist
|
|
55
|
+
elseif current_owner ~= ARGV[1] then
|
|
56
|
+
return -2 -- Wrong owner
|
|
57
|
+
else
|
|
58
|
+
return redis.call("DEL", KEYS[1]) -- Success (returns 1)
|
|
59
|
+
end
|
|
60
|
+
"""
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class BaseRedisClient:
|
|
64
|
+
"""Base Redis client with common functionality."""
|
|
65
|
+
|
|
66
|
+
def __init__(self):
|
|
67
|
+
"""Initialize Redis client configuration."""
|
|
68
|
+
if IS_LOCKING_DISABLED:
|
|
69
|
+
logger.info("Strict locking disabled - skipping Redis connection")
|
|
70
|
+
return
|
|
71
|
+
|
|
72
|
+
# Validate Redis configuration
|
|
73
|
+
if not REDIS_PASSWORD or (
|
|
74
|
+
not REDIS_SENTINEL_HOSTS and not (REDIS_HOST and REDIS_PORT)
|
|
75
|
+
):
|
|
76
|
+
logger.error(
|
|
77
|
+
"Redis configuration invalid: REDIS_PASSWORD is required and either REDIS_SENTINEL_HOSTS or REDIS_HOST/REDIS_PORT must be configured"
|
|
78
|
+
)
|
|
79
|
+
raise ClientError(
|
|
80
|
+
f"{ClientError.REQUEST_VALIDATION_ERROR}: Redis configuration invalid - REDIS_PASSWORD is required and either REDIS_SENTINEL_HOSTS or REDIS_HOST/REDIS_PORT must be configured"
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
def _parse_sentinel_hosts(self) -> list[tuple[str, int]]:
|
|
84
|
+
"""Parse sentinel hosts from configuration.
|
|
85
|
+
|
|
86
|
+
Returns:
|
|
87
|
+
List of (host, port) tuples
|
|
88
|
+
|
|
89
|
+
Raises:
|
|
90
|
+
ValueError: If host format is invalid
|
|
91
|
+
ClientError: If no hosts are configured
|
|
92
|
+
"""
|
|
93
|
+
try:
|
|
94
|
+
sentinel_hosts = [
|
|
95
|
+
(host.strip(), int(port))
|
|
96
|
+
for host_port in REDIS_SENTINEL_HOSTS.split(",")
|
|
97
|
+
for host, port in [host_port.strip().rsplit(":", 1)]
|
|
98
|
+
]
|
|
99
|
+
except ValueError as e:
|
|
100
|
+
logger.error(
|
|
101
|
+
f"Invalid Sentinel host format in REDIS_SENTINEL_HOSTS '{REDIS_SENTINEL_HOSTS}': {e}"
|
|
102
|
+
)
|
|
103
|
+
raise
|
|
104
|
+
|
|
105
|
+
if not sentinel_hosts:
|
|
106
|
+
logger.error("No Sentinel hosts configured")
|
|
107
|
+
raise ClientError(
|
|
108
|
+
f"{ClientError.REQUEST_VALIDATION_ERROR}: No Sentinel hosts configured"
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
return sentinel_hosts
|
|
112
|
+
|
|
113
|
+
def _process_lock_release_result(
|
|
114
|
+
self, result: Union[int, None], resource_id: str
|
|
115
|
+
) -> tuple[bool, LockReleaseResult]:
|
|
116
|
+
"""Process lock release Lua script result.
|
|
117
|
+
|
|
118
|
+
Args:
|
|
119
|
+
result (int | None): Result from Redis eval command.
|
|
120
|
+
resource_id (str): Resource ID for logging.
|
|
121
|
+
|
|
122
|
+
Returns:
|
|
123
|
+
tuple[bool, LockReleaseResult]: A tuple ``(success, outcome)``.
|
|
124
|
+
|
|
125
|
+
Raises:
|
|
126
|
+
ClientError: If result type is unexpected or unknown.
|
|
127
|
+
"""
|
|
128
|
+
if not isinstance(result, int):
|
|
129
|
+
logger.error(
|
|
130
|
+
f"Unexpected eval result type for {resource_id}: {type(result)}, value: {result}"
|
|
131
|
+
)
|
|
132
|
+
raise ClientError(
|
|
133
|
+
f"{ClientError.REDIS_CONNECTION_ERROR}: Redis connection failed"
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
if result >= 1:
|
|
137
|
+
return True, LockReleaseResult.SUCCESS
|
|
138
|
+
elif result == -1:
|
|
139
|
+
return (
|
|
140
|
+
True,
|
|
141
|
+
LockReleaseResult.ALREADY_RELEASED,
|
|
142
|
+
) # Not an error - TTL expired
|
|
143
|
+
elif result == -2:
|
|
144
|
+
return False, LockReleaseResult.WRONG_OWNER
|
|
145
|
+
else:
|
|
146
|
+
logger.error(f"Unknown Redis eval result for {resource_id}: {result}")
|
|
147
|
+
raise ClientError(
|
|
148
|
+
f"{ClientError.REDIS_CONNECTION_ERROR}: Redis connection failed"
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
class RedisClient(BaseRedisClient):
|
|
153
|
+
"""Synchronous Redis client for distributed locking."""
|
|
154
|
+
|
|
155
|
+
def __init__(self):
|
|
156
|
+
"""Initialize sync Redis client."""
|
|
157
|
+
super().__init__()
|
|
158
|
+
self.redis_client = None
|
|
159
|
+
|
|
160
|
+
def _connect(self) -> None:
|
|
161
|
+
"""Establish sync Redis connection."""
|
|
162
|
+
if IS_LOCKING_DISABLED:
|
|
163
|
+
logger.info("Locking disabled - Redis client will operate in no-op mode")
|
|
164
|
+
return
|
|
165
|
+
|
|
166
|
+
try:
|
|
167
|
+
if REDIS_SENTINEL_HOSTS:
|
|
168
|
+
self._connect_via_sentinel()
|
|
169
|
+
else:
|
|
170
|
+
self._connect_standalone()
|
|
171
|
+
|
|
172
|
+
# Test connection
|
|
173
|
+
if not self.redis_client:
|
|
174
|
+
raise ClientError(
|
|
175
|
+
f"{ClientError.REDIS_CONNECTION_ERROR}: Redis connection failed"
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
self.redis_client.ping()
|
|
179
|
+
logger.info("Sync Redis connection established for strict locking")
|
|
180
|
+
|
|
181
|
+
except (ConnectionError, TimeoutError, RedisError, Exception) as e:
|
|
182
|
+
_handle_redis_error(e)
|
|
183
|
+
|
|
184
|
+
def _connect_via_sentinel(self) -> None:
|
|
185
|
+
"""Connect to Redis via Sentinel using sync client."""
|
|
186
|
+
sentinel_hosts = self._parse_sentinel_hosts()
|
|
187
|
+
logger.info(f"Connecting to Redis via sync Sentinel: {sentinel_hosts}")
|
|
188
|
+
logger.info(f"Service name: {REDIS_SENTINEL_SERVICE_NAME}")
|
|
189
|
+
|
|
190
|
+
try:
|
|
191
|
+
# Create Sentinel with password
|
|
192
|
+
sentinel = redis.sentinel.Sentinel(
|
|
193
|
+
sentinel_hosts, sentinel_kwargs={"password": REDIS_PASSWORD}
|
|
194
|
+
)
|
|
195
|
+
|
|
196
|
+
# Create master client with password
|
|
197
|
+
self.redis_client = sentinel.master_for(
|
|
198
|
+
REDIS_SENTINEL_SERVICE_NAME, password=REDIS_PASSWORD
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
except (ConnectionError, TimeoutError, RedisError, Exception) as e:
|
|
202
|
+
_handle_redis_error(e)
|
|
203
|
+
|
|
204
|
+
def _connect_standalone(self) -> None:
|
|
205
|
+
"""Connect to standalone Redis instance using sync client."""
|
|
206
|
+
logger.debug(f"Connecting to standalone sync Redis: {REDIS_HOST}:{REDIS_PORT}")
|
|
207
|
+
|
|
208
|
+
try:
|
|
209
|
+
self.redis_client = redis.Redis(
|
|
210
|
+
host=REDIS_HOST, port=int(REDIS_PORT), password=REDIS_PASSWORD
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
except (ConnectionError, TimeoutError, RedisError, Exception) as e:
|
|
214
|
+
_handle_redis_error(e)
|
|
215
|
+
|
|
216
|
+
def close(self) -> None:
|
|
217
|
+
"""Close the sync Redis client and clean up resources."""
|
|
218
|
+
if self.redis_client:
|
|
219
|
+
try:
|
|
220
|
+
self.redis_client.close()
|
|
221
|
+
logger.info("Sync Redis connection closed")
|
|
222
|
+
except Exception as e:
|
|
223
|
+
logger.error(f"Error closing sync Redis connection: {e}")
|
|
224
|
+
finally:
|
|
225
|
+
self.redis_client = None
|
|
226
|
+
|
|
227
|
+
def __enter__(self):
|
|
228
|
+
"""Sync context manager entry."""
|
|
229
|
+
self._connect()
|
|
230
|
+
return self
|
|
231
|
+
|
|
232
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
233
|
+
"""Sync context manager exit with guaranteed cleanup."""
|
|
234
|
+
self.close()
|
|
235
|
+
|
|
236
|
+
def _acquire_lock(
|
|
237
|
+
self, resource_id: str, owner_id: str = "default_owner", ttl_seconds: int = 100
|
|
238
|
+
) -> bool:
|
|
239
|
+
"""Synchronously acquire a distributed lock.
|
|
240
|
+
|
|
241
|
+
Args:
|
|
242
|
+
resource_id: Unique identifier for the resource to lock
|
|
243
|
+
owner_id: Identifier for the lock owner
|
|
244
|
+
ttl_seconds: Time-to-live for the lock in seconds
|
|
245
|
+
|
|
246
|
+
Returns:
|
|
247
|
+
True if lock was acquired, False if lock is already held by another owner
|
|
248
|
+
|
|
249
|
+
Raises:
|
|
250
|
+
ClientError: If Redis connection or operation fails
|
|
251
|
+
"""
|
|
252
|
+
if not self.redis_client:
|
|
253
|
+
logger.error("Sync Redis client not initialized")
|
|
254
|
+
raise ClientError(
|
|
255
|
+
f"{ClientError.REDIS_CONNECTION_ERROR}: Redis connection failed"
|
|
256
|
+
)
|
|
257
|
+
|
|
258
|
+
try:
|
|
259
|
+
result = self.redis_client.set(
|
|
260
|
+
resource_id, owner_id, nx=True, ex=ttl_seconds
|
|
261
|
+
)
|
|
262
|
+
return bool(result)
|
|
263
|
+
except (ConnectionError, TimeoutError, RedisError, Exception) as e:
|
|
264
|
+
_handle_redis_error(e)
|
|
265
|
+
|
|
266
|
+
def _release_lock(
|
|
267
|
+
self, resource_id: str, owner_id: str = "default_owner"
|
|
268
|
+
) -> tuple[bool, LockReleaseResult]:
|
|
269
|
+
"""Synchronously release a lock with ownership verification.
|
|
270
|
+
|
|
271
|
+
Args:
|
|
272
|
+
resource_id (str): Unique identifier for the resource to unlock.
|
|
273
|
+
owner_id (str): Identifier for the lock owner.
|
|
274
|
+
|
|
275
|
+
Returns:
|
|
276
|
+
tuple[bool, LockReleaseResult]: Result of the release operation.
|
|
277
|
+
- (True, LockReleaseResult.SUCCESS): Lock released successfully.
|
|
278
|
+
- (True, LockReleaseResult.ALREADY_RELEASED): Lock was already released (TTL expired).
|
|
279
|
+
- (False, LockReleaseResult.WRONG_OWNER): Lock owned by a different owner.
|
|
280
|
+
|
|
281
|
+
Raises:
|
|
282
|
+
ClientError: If Redis connection or operation fails.
|
|
283
|
+
"""
|
|
284
|
+
if not self.redis_client:
|
|
285
|
+
logger.error("Sync Redis client not initialized")
|
|
286
|
+
raise ClientError(
|
|
287
|
+
f"{ClientError.REDIS_CONNECTION_ERROR}: Redis connection failed"
|
|
288
|
+
)
|
|
289
|
+
|
|
290
|
+
try:
|
|
291
|
+
result = self.redis_client.eval(
|
|
292
|
+
_LOCK_RELEASE_LUA_SCRIPT, 1, resource_id, owner_id
|
|
293
|
+
)
|
|
294
|
+
return self._process_lock_release_result(result, resource_id)
|
|
295
|
+
except (ConnectionError, TimeoutError, RedisError, Exception) as e:
|
|
296
|
+
_handle_redis_error(e)
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
class RedisClientAsync(BaseRedisClient):
|
|
300
|
+
"""Asynchronous Redis client for distributed locking."""
|
|
301
|
+
|
|
302
|
+
def __init__(self):
|
|
303
|
+
"""Initialize async Redis client."""
|
|
304
|
+
super().__init__()
|
|
305
|
+
self.redis_client = None
|
|
306
|
+
|
|
307
|
+
async def _connect(self) -> None:
|
|
308
|
+
"""Establish async Redis connection."""
|
|
309
|
+
if IS_LOCKING_DISABLED:
|
|
310
|
+
logger.info("Locking disabled - Redis client will operate in no-op mode")
|
|
311
|
+
return
|
|
312
|
+
|
|
313
|
+
try:
|
|
314
|
+
if REDIS_SENTINEL_HOSTS:
|
|
315
|
+
await self._connect_via_sentinel()
|
|
316
|
+
else:
|
|
317
|
+
await self._connect_standalone()
|
|
318
|
+
|
|
319
|
+
# Test connection
|
|
320
|
+
if not self.redis_client:
|
|
321
|
+
raise ClientError(
|
|
322
|
+
f"{ClientError.REDIS_CONNECTION_ERROR}: Redis connection failed"
|
|
323
|
+
)
|
|
324
|
+
|
|
325
|
+
await self.redis_client.ping()
|
|
326
|
+
logger.info("Async Redis connection established for strict locking")
|
|
327
|
+
|
|
328
|
+
except (ConnectionError, TimeoutError, RedisError, Exception) as e:
|
|
329
|
+
_handle_redis_error(e)
|
|
330
|
+
|
|
331
|
+
async def _connect_via_sentinel(self) -> None:
|
|
332
|
+
"""Connect to Redis via Sentinel using async client."""
|
|
333
|
+
sentinel_hosts = self._parse_sentinel_hosts()
|
|
334
|
+
logger.info(f"Connecting to Redis via async Sentinel: {sentinel_hosts}")
|
|
335
|
+
logger.info(f"Service name: {REDIS_SENTINEL_SERVICE_NAME}")
|
|
336
|
+
|
|
337
|
+
try:
|
|
338
|
+
# Create Sentinel with password
|
|
339
|
+
sentinel = async_redis.sentinel.Sentinel(
|
|
340
|
+
sentinel_hosts, sentinel_kwargs={"password": REDIS_PASSWORD}
|
|
341
|
+
)
|
|
342
|
+
|
|
343
|
+
# Create master client with password
|
|
344
|
+
self.redis_client = sentinel.master_for(
|
|
345
|
+
REDIS_SENTINEL_SERVICE_NAME, password=REDIS_PASSWORD
|
|
346
|
+
)
|
|
347
|
+
|
|
348
|
+
except (ConnectionError, TimeoutError, RedisError, Exception) as e:
|
|
349
|
+
_handle_redis_error(e)
|
|
350
|
+
|
|
351
|
+
async def _connect_standalone(self) -> None:
|
|
352
|
+
"""Connect to standalone Redis instance using async client."""
|
|
353
|
+
logger.debug(f"Connecting to standalone async Redis: {REDIS_HOST}:{REDIS_PORT}")
|
|
354
|
+
|
|
355
|
+
try:
|
|
356
|
+
self.redis_client = async_redis.Redis(
|
|
357
|
+
host=REDIS_HOST, port=int(REDIS_PORT), password=REDIS_PASSWORD
|
|
358
|
+
)
|
|
359
|
+
|
|
360
|
+
except (ConnectionError, TimeoutError, RedisError, Exception) as e:
|
|
361
|
+
_handle_redis_error(e)
|
|
362
|
+
|
|
363
|
+
async def close(self) -> None:
|
|
364
|
+
"""Close the Redis client and clean up resources."""
|
|
365
|
+
if self.redis_client:
|
|
366
|
+
try:
|
|
367
|
+
await self.redis_client.aclose()
|
|
368
|
+
logger.info("Async Redis connection closed")
|
|
369
|
+
except Exception as e:
|
|
370
|
+
logger.error(f"Error closing async Redis connection: {e}")
|
|
371
|
+
finally:
|
|
372
|
+
self.redis_client = None
|
|
373
|
+
|
|
374
|
+
async def __aenter__(self):
|
|
375
|
+
"""Async context manager entry."""
|
|
376
|
+
await self._connect()
|
|
377
|
+
return self
|
|
378
|
+
|
|
379
|
+
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
|
380
|
+
"""Async context manager exit with guaranteed cleanup."""
|
|
381
|
+
await self.close()
|
|
382
|
+
|
|
383
|
+
async def _acquire_lock(
|
|
384
|
+
self, resource_id: str, owner_id: str = "default_owner", ttl_seconds: int = 100
|
|
385
|
+
) -> bool:
|
|
386
|
+
"""Asynchronously acquire a distributed lock.
|
|
387
|
+
|
|
388
|
+
Args:
|
|
389
|
+
resource_id: Unique identifier for the resource to lock
|
|
390
|
+
owner_id: Identifier for the lock owner
|
|
391
|
+
ttl_seconds: Time-to-live for the lock in seconds
|
|
392
|
+
|
|
393
|
+
Returns:
|
|
394
|
+
True if lock was acquired, False if lock is already held by another owner
|
|
395
|
+
|
|
396
|
+
Raises:
|
|
397
|
+
ClientError: If Redis connection or operation fails
|
|
398
|
+
"""
|
|
399
|
+
if not self.redis_client:
|
|
400
|
+
logger.error("Redis client not initialized")
|
|
401
|
+
raise ClientError(
|
|
402
|
+
f"{ClientError.REDIS_CONNECTION_ERROR}: Redis connection failed"
|
|
403
|
+
)
|
|
404
|
+
|
|
405
|
+
try:
|
|
406
|
+
result = await self.redis_client.set(
|
|
407
|
+
resource_id, owner_id, nx=True, ex=ttl_seconds
|
|
408
|
+
)
|
|
409
|
+
return bool(result)
|
|
410
|
+
except (ConnectionError, TimeoutError, RedisError, Exception) as e:
|
|
411
|
+
_handle_redis_error(e)
|
|
412
|
+
|
|
413
|
+
async def _release_lock(
|
|
414
|
+
self, resource_id: str, owner_id: str = "default_owner"
|
|
415
|
+
) -> tuple[bool, LockReleaseResult]:
|
|
416
|
+
"""Asynchronously release a lock with ownership verification.
|
|
417
|
+
|
|
418
|
+
Args:
|
|
419
|
+
resource_id (str): Unique identifier for the resource to unlock.
|
|
420
|
+
owner_id (str): Identifier for the lock owner.
|
|
421
|
+
|
|
422
|
+
Returns:
|
|
423
|
+
tuple[bool, LockReleaseResult]: Result of the release operation.
|
|
424
|
+
- (True, LockReleaseResult.SUCCESS): Lock released successfully.
|
|
425
|
+
- (True, LockReleaseResult.ALREADY_RELEASED): Lock was already released (TTL expired).
|
|
426
|
+
- (False, LockReleaseResult.WRONG_OWNER): Lock owned by a different owner.
|
|
427
|
+
|
|
428
|
+
Raises:
|
|
429
|
+
ClientError: If Redis connection or operation fails.
|
|
430
|
+
"""
|
|
431
|
+
if not self.redis_client:
|
|
432
|
+
logger.error("Redis client not initialized")
|
|
433
|
+
raise ClientError(
|
|
434
|
+
f"{ClientError.REDIS_CONNECTION_ERROR}: Redis connection failed"
|
|
435
|
+
)
|
|
436
|
+
|
|
437
|
+
try:
|
|
438
|
+
result = await self.redis_client.eval(
|
|
439
|
+
_LOCK_RELEASE_LUA_SCRIPT, 1, resource_id, owner_id
|
|
440
|
+
)
|
|
441
|
+
return self._process_lock_release_result(result, resource_id)
|
|
442
|
+
except (ConnectionError, TimeoutError, RedisError, Exception) as e:
|
|
443
|
+
_handle_redis_error(e)
|