Skip to content

feat(templates): add EntityDef and entity-driven orchestration to SqlMetadataExtractor#1298

Closed
AtMrun wants to merge 8 commits intomainfrom
feat/entity-registry-v3
Closed

feat(templates): add EntityDef and entity-driven orchestration to SqlMetadataExtractor#1298
AtMrun wants to merge 8 commits intomainfrom
feat/entity-registry-v3

Conversation

@AtMrun
Copy link
Copy Markdown
Collaborator

@AtMrun AtMrun commented Apr 13, 2026

Summary

  • Introduces EntityDef frozen dataclass for declarative entity definitions (name, sql, endpoint, phase, enabled, timeout, result_key, depends_on)
  • Replaces hardcoded asyncio.gather of 4 entities in SqlMetadataExtractor.run() with phased orchestration — entities grouped by phase run concurrently within phase, sequentially across phases
  • _fetch_entity() dispatches to fetch_{name}() methods by convention; _get_entities() falls back to default 4 (databases, schemas, tables, columns) when entities is empty
  • Preserves v3-specific features: BaseMetadataExtractor base class, upload_to_atlan step, rewrap error handling
  • Port of feat(templates): add EntityDef and entity-driven orchestration to Sql… #1297 adapted for refactor-v3

Test plan

  • 17 new unit tests in test_entity_registry.py covering EntityDef, _get_entities, _fetch_entity, and phase grouping
  • All 37 existing test_sql_metadata_extractor.py tests pass
  • Pre-commit (ruff, ruff-format, isort, pyright) passes

🤖 Generated with Claude Code

…MetadataExtractor

Introduces declarative entity definitions that replace hardcoded
asyncio.gather of 4 entities in SqlMetadataExtractor.run().

- EntityDef dataclass: name, sql, endpoint, phase, enabled, timeout
- Phased orchestration: entities grouped by phase, run concurrently
  within phase, sequentially across phases
- _fetch_entity() dispatches to fetch_{name}() methods by convention
- Full backward compat: empty entities list falls back to default 4
- Adding a new entity type is one line in the entities list
@snykgituser
Copy link
Copy Markdown

snykgituser commented Apr 13, 2026

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues
Licenses 0 0 0 0 0 issues
Code Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 13, 2026

📜 Docstring Coverage Report

RESULT: PASSED (minimum: 30.0%, actual: 79.7%)

Detailed Coverage Report
======= Coverage for /home/runner/work/application-sdk/application-sdk/ ========
----------------------------------- Summary ------------------------------------
| Name                                                                              | Total | Miss | Cover | Cover% |
|-----------------------------------------------------------------------------------|-------|------|-------|--------|
| application_sdk/__init__.py                                                       |     1 |    0 |     1 |   100% |
| application_sdk/constants.py                                                      |     2 |    0 |     2 |   100% |
| application_sdk/discovery.py                                                      |    11 |    2 |     9 |    82% |
| application_sdk/errors.py                                                         |     4 |    1 |     3 |    75% |
| application_sdk/main.py                                                           |    27 |    6 |    21 |    78% |
| application_sdk/version.py                                                        |     1 |    0 |     1 |   100% |
| application_sdk/worker.py                                                         |     8 |    1 |     7 |    88% |
| application_sdk/activities/__init__.py                                            |    10 |    0 |    10 |   100% |
| application_sdk/activities/lock_management.py                                     |     1 |    0 |     1 |   100% |
| application_sdk/activities/common/__init__.py                                     |     1 |    1 |     0 |     0% |
| application_sdk/activities/common/models.py                                       |     1 |    0 |     1 |   100% |
| application_sdk/activities/common/sql_utils.py                                    |     1 |    0 |     1 |   100% |
| application_sdk/activities/common/utils.py                                        |     1 |    0 |     1 |   100% |
| application_sdk/activities/metadata_extraction/__init__.py                        |     1 |    1 |     0 |     0% |
| application_sdk/activities/metadata_extraction/base.py                            |     6 |    1 |     5 |    83% |
| application_sdk/activities/metadata_extraction/incremental.py                     |    20 |    0 |    20 |   100% |
| application_sdk/activities/metadata_extraction/sql.py                             |    20 |    3 |    17 |    85% |
| application_sdk/activities/query_extraction/__init__.py                           |     1 |    1 |     0 |     0% |
| application_sdk/activities/query_extraction/sql.py                                |    13 |    1 |    12 |    92% |
| application_sdk/app/__init__.py                                                   |     1 |    0 |     1 |   100% |
| application_sdk/app/base.py                                                       |    68 |   12 |    56 |    82% |
| application_sdk/app/client.py                                                     |     5 |    0 |     5 |   100% |
| application_sdk/app/context.py                                                    |    38 |    2 |    36 |    95% |
| application_sdk/app/registry.py                                                   |    34 |    8 |    26 |    76% |
| application_sdk/app/task.py                                                       |    12 |    5 |     7 |    58% |
| application_sdk/application/__init__.py                                           |    15 |    6 |     9 |    60% |
| application_sdk/application/metadata_extraction/sql.py                            |    12 |    4 |     8 |    67% |
| application_sdk/clients/__init__.py                                               |     4 |    0 |     4 |   100% |
| application_sdk/clients/atlan.py                                                  |     5 |    3 |     2 |    40% |
| application_sdk/clients/atlan_auth.py                                             |    10 |    0 |    10 |   100% |
| application_sdk/clients/base.py                                                   |     6 |    1 |     5 |    83% |
| application_sdk/clients/models.py                                                 |     2 |    0 |     2 |   100% |
| application_sdk/clients/redis.py                                                  |    27 |    0 |    27 |   100% |
| application_sdk/clients/sql.py                                                    |    24 |    1 |    23 |    96% |
| application_sdk/clients/temporal.py                                               |    15 |    1 |    14 |    93% |
| application_sdk/clients/utils.py                                                  |     2 |    1 |     1 |    50% |
| application_sdk/clients/workflow.py                                               |     9 |    2 |     7 |    78% |
| application_sdk/clients/azure/__init__.py                                         |     1 |    0 |     1 |   100% |
| application_sdk/clients/azure/auth.py                                             |     7 |    0 |     7 |   100% |
| application_sdk/clients/azure/client.py                                           |    13 |    0 |    13 |   100% |
| application_sdk/common/__init__.py                                                |     1 |    1 |     0 |     0% |
| application_sdk/common/aws_utils.py                                               |    10 |    1 |     9 |    90% |
| application_sdk/common/error_codes.py                                             |    14 |    2 |    12 |    86% |
| application_sdk/common/exc_utils.py                                               |     2 |    0 |     2 |   100% |
| application_sdk/common/file_converter.py                                          |     9 |    5 |     4 |    44% |
| application_sdk/common/file_ops.py                                                |    16 |    1 |    15 |    94% |
| application_sdk/common/models.py                                                  |     4 |    2 |     2 |    50% |
| application_sdk/common/path.py                                                    |     2 |    1 |     1 |    50% |
| application_sdk/common/sql_utils.py                                               |     6 |    1 |     5 |    83% |
| application_sdk/common/types.py                                                   |     2 |    1 |     1 |    50% |
| application_sdk/common/utils.py                                                   |    17 |    2 |    15 |    88% |
| application_sdk/common/incremental/__init__.py                                    |     1 |    1 |     0 |     0% |
| application_sdk/common/incremental/helpers.py                                     |    12 |    0 |    12 |   100% |
| application_sdk/common/incremental/marker.py                                      |     5 |    0 |     5 |   100% |
| application_sdk/common/incremental/models.py                                      |    11 |    0 |    11 |   100% |
| application_sdk/common/incremental/column_extraction/__init__.py                  |     1 |    0 |     1 |   100% |
| application_sdk/common/incremental/column_extraction/analysis.py                  |     3 |    0 |     3 |   100% |
| application_sdk/common/incremental/column_extraction/backfill.py                  |     3 |    0 |     3 |   100% |
| application_sdk/common/incremental/state/__init__.py                              |     1 |    1 |     0 |     0% |
| application_sdk/common/incremental/state/ancestral_merge.py                       |     3 |    0 |     3 |   100% |
| application_sdk/common/incremental/state/incremental_diff.py                      |     4 |    0 |     4 |   100% |
| application_sdk/common/incremental/state/state_reader.py                          |     2 |    0 |     2 |   100% |
| application_sdk/common/incremental/state/state_writer.py                          |     9 |    0 |     9 |   100% |
| application_sdk/common/incremental/state/table_scope.py                           |     8 |    0 |     8 |   100% |
| application_sdk/common/incremental/storage/__init__.py                            |     1 |    1 |     0 |     0% |
| application_sdk/common/incremental/storage/duckdb_utils.py                        |    12 |    2 |    10 |    83% |
| application_sdk/common/incremental/storage/rocksdb_utils.py                       |     3 |    0 |     3 |   100% |
| application_sdk/contracts/__init__.py                                             |     1 |    0 |     1 |   100% |
| application_sdk/contracts/base.py                                                 |    35 |    6 |    29 |    83% |
| application_sdk/contracts/cleanup.py                                              |     5 |    0 |     5 |   100% |
| application_sdk/contracts/events.py                                               |    12 |    0 |    12 |   100% |
| application_sdk/contracts/storage.py                                              |     6 |    1 |     5 |    83% |
| application_sdk/contracts/types.py                                                |    14 |    0 |    14 |   100% |
| application_sdk/credentials/__init__.py                                           |     1 |    0 |     1 |   100% |
| application_sdk/credentials/atlan.py                                              |    12 |    6 |     6 |    50% |
| application_sdk/credentials/atlan_client.py                                       |     4 |    0 |     4 |   100% |
| application_sdk/credentials/errors.py                                             |     9 |    4 |     5 |    56% |
| application_sdk/credentials/git.py                                                |     9 |    6 |     3 |    33% |
| application_sdk/credentials/oauth.py                                              |     9 |    1 |     8 |    89% |
| application_sdk/credentials/ref.py                                                |    13 |    1 |    12 |    92% |
| application_sdk/credentials/registry.py                                           |    11 |    3 |     8 |    73% |
| application_sdk/credentials/resolver.py                                           |     9 |    4 |     5 |    56% |
| application_sdk/credentials/types.py                                              |    35 |   17 |    18 |    51% |
| application_sdk/decorators/__init__.py                                            |     1 |    1 |     0 |     0% |
| application_sdk/decorators/locks.py                                               |     3 |    2 |     1 |    33% |
| application_sdk/decorators/mcp_tool.py                                            |     3 |    1 |     2 |    67% |
| application_sdk/execution/__init__.py                                             |     1 |    0 |     1 |   100% |
| application_sdk/execution/errors.py                                               |     2 |    0 |     2 |   100% |
| application_sdk/execution/heartbeat.py                                            |    17 |    2 |    15 |    88% |
| application_sdk/execution/retry.py                                                |     6 |    0 |     6 |   100% |
| application_sdk/execution/sandbox.py                                              |     4 |    0 |     4 |   100% |
| application_sdk/execution/settings.py                                             |     6 |    1 |     5 |    83% |
| application_sdk/execution/_temporal/__init__.py                                   |     1 |    1 |     0 |     0% |
| application_sdk/execution/_temporal/activities.py                                 |     8 |    0 |     8 |   100% |
| application_sdk/execution/_temporal/activity_utils.py                             |    11 |    2 |     9 |    82% |
| application_sdk/execution/_temporal/auth.py                                       |    12 |    0 |    12 |   100% |
| application_sdk/execution/_temporal/backend.py                                    |     9 |    1 |     8 |    89% |
| application_sdk/execution/_temporal/converter.py                                  |     3 |    0 |     3 |   100% |
| application_sdk/execution/_temporal/lock_activities.py                            |     3 |    0 |     3 |   100% |
| application_sdk/execution/_temporal/worker.py                                     |     8 |    3 |     5 |    62% |
| application_sdk/execution/_temporal/workflows.py                                  |     2 |    0 |     2 |   100% |
| application_sdk/execution/_temporal/interceptors/__init__.py                      |     1 |    0 |     1 |   100% |
| application_sdk/execution/_temporal/interceptors/activity_failure_logging.py      |     8 |    0 |     8 |   100% |
| application_sdk/execution/_temporal/interceptors/cleanup.py                       |     7 |    1 |     6 |    86% |
| application_sdk/execution/_temporal/interceptors/correlation_context.py           |    13 |    0 |    13 |   100% |
| application_sdk/execution/_temporal/interceptors/correlation_interceptor.py       |    15 |   10 |     5 |    33% |
| application_sdk/execution/_temporal/interceptors/events.py                        |    13 |    0 |    13 |   100% |
| application_sdk/execution/_temporal/interceptors/execution_context_interceptor.py |     8 |    4 |     4 |    50% |
| application_sdk/execution/_temporal/interceptors/lock.py                          |    10 |    2 |     8 |    80% |
| application_sdk/execution/_temporal/interceptors/outputs.py                       |     9 |    0 |     9 |   100% |
| application_sdk/handler/__init__.py                                               |     1 |    0 |     1 |   100% |
| application_sdk/handler/base.py                                                   |    13 |    2 |    11 |    85% |
| application_sdk/handler/context.py                                                |    15 |    5 |    10 |    67% |
| application_sdk/handler/contracts.py                                              |    24 |    2 |    22 |    92% |
| application_sdk/handler/manifest.py                                               |     5 |    0 |     5 |   100% |
| application_sdk/handler/service.py                                                |    37 |   22 |    15 |    41% |
| application_sdk/handlers/__init__.py                                              |     8 |    1 |     7 |    88% |
| application_sdk/handlers/base.py                                                  |     7 |    1 |     6 |    86% |
| application_sdk/handlers/sql.py                                                   |    19 |    6 |    13 |    68% |
| application_sdk/infrastructure/__init__.py                                        |     1 |    0 |     1 |   100% |
| application_sdk/infrastructure/bindings.py                                        |    23 |    4 |    19 |    83% |
| application_sdk/infrastructure/capacity.py                                        |    11 |    0 |    11 |   100% |
| application_sdk/infrastructure/context.py                                         |     4 |    0 |     4 |   100% |
| application_sdk/infrastructure/pubsub.py                                          |    25 |    7 |    18 |    72% |
| application_sdk/infrastructure/secrets.py                                         |    26 |    5 |    21 |    81% |
| application_sdk/infrastructure/state.py                                           |    17 |   13 |     4 |    24% |
| application_sdk/infrastructure/_dapr/__init__.py                                  |     1 |    0 |     1 |   100% |
| application_sdk/infrastructure/_dapr/client.py                                    |    28 |    4 |    24 |    86% |
| application_sdk/infrastructure/_redis/__init__.py                                 |     1 |    0 |     1 |   100% |
| application_sdk/infrastructure/_redis/capacity.py                                 |     9 |    4 |     5 |    56% |
| application_sdk/interceptors/__init__.py                                          |     1 |    1 |     0 |     0% |
| application_sdk/interceptors/activity_failure_logging.py                          |     1 |    0 |     1 |   100% |
| application_sdk/interceptors/cleanup.py                                           |     1 |    0 |     1 |   100% |
| application_sdk/interceptors/correlation_context.py                               |     1 |    0 |     1 |   100% |
| application_sdk/interceptors/events.py                                            |     1 |    0 |     1 |   100% |
| application_sdk/interceptors/lock.py                                              |     1 |    0 |     1 |   100% |
| application_sdk/interceptors/models.py                                            |     1 |    0 |     1 |   100% |
| application_sdk/io/__init__.py                                                    |    25 |    0 |    25 |   100% |
| application_sdk/io/json.py                                                        |    15 |    1 |    14 |    93% |
| application_sdk/io/parquet.py                                                     |    22 |    1 |    21 |    95% |
| application_sdk/io/utils.py                                                       |     9 |    2 |     7 |    78% |
| application_sdk/observability/__init__.py                                         |     1 |    1 |     0 |     0% |
| application_sdk/observability/context.py                                          |     4 |    0 |     4 |   100% |
| application_sdk/observability/correlation.py                                      |     6 |    0 |     6 |   100% |
| application_sdk/observability/logger_adaptor.py                                   |    34 |    2 |    32 |    94% |
| application_sdk/observability/metrics_adaptor.py                                  |    12 |    1 |    11 |    92% |
| application_sdk/observability/models.py                                           |     4 |    0 |     4 |   100% |
| application_sdk/observability/observability.py                                    |    23 |    3 |    20 |    87% |
| application_sdk/observability/segment_client.py                                   |    14 |    2 |    12 |    86% |
| application_sdk/observability/traces_adaptor.py                                   |    15 |    1 |    14 |    93% |
| application_sdk/observability/utils.py                                            |     5 |    1 |     4 |    80% |
| application_sdk/observability/decorators/observability_decorator.py               |     7 |    4 |     3 |    43% |
| application_sdk/server/__init__.py                                                |     4 |    0 |     4 |   100% |
| application_sdk/server/health.py                                                  |    20 |    0 |    20 |   100% |
| application_sdk/server/fastapi/__init__.py                                        |    25 |    5 |    20 |    80% |
| application_sdk/server/fastapi/models.py                                          |    25 |   21 |     4 |    16% |
| application_sdk/server/fastapi/utils.py                                           |     5 |    0 |     5 |   100% |
| application_sdk/server/fastapi/middleware/logmiddleware.py                        |     1 |    1 |     0 |     0% |
| application_sdk/server/fastapi/middleware/metrics.py                              |     1 |    1 |     0 |     0% |
| application_sdk/server/fastapi/routers/__init__.py                                |     1 |    1 |     0 |     0% |
| application_sdk/server/fastapi/routers/server.py                                  |     8 |    2 |     6 |    75% |
| application_sdk/server/mcp/__init__.py                                            |     1 |    1 |     0 |     0% |
| application_sdk/server/mcp/models.py                                              |     2 |    2 |     0 |     0% |
| application_sdk/server/mcp/server.py                                              |     6 |    0 |     6 |   100% |
| application_sdk/server/middleware/__init__.py                                     |     1 |    0 |     1 |   100% |
| application_sdk/server/middleware/_constants.py                                   |     1 |    0 |     1 |   100% |
| application_sdk/server/middleware/log.py                                          |     4 |    3 |     1 |    25% |
| application_sdk/server/middleware/metrics.py                                      |     3 |    2 |     1 |    33% |
| application_sdk/services/__init__.py                                              |     1 |    0 |     1 |   100% |
| application_sdk/services/_utils.py                                                |     2 |    1 |     1 |    50% |
| application_sdk/services/atlan_storage.py                                         |     7 |    2 |     5 |    71% |
| application_sdk/services/eventstore.py                                            |     5 |    0 |     5 |   100% |
| application_sdk/services/objectstore.py                                           |    17 |    0 |    17 |   100% |
| application_sdk/services/secretstore.py                                           |    14 |    0 |    14 |   100% |
| application_sdk/services/statestore.py                                            |     9 |    1 |     8 |    89% |
| application_sdk/storage/__init__.py                                               |     1 |    0 |     1 |   100% |
| application_sdk/storage/binding.py                                                |     3 |    0 |     3 |   100% |
| application_sdk/storage/errors.py                                                 |     8 |    3 |     5 |    62% |
| application_sdk/storage/factory.py                                                |     3 |    0 |     3 |   100% |
| application_sdk/storage/file_ref_sync.py                                          |     9 |    0 |     9 |   100% |
| application_sdk/storage/ops.py                                                    |    13 |    0 |    13 |   100% |
| application_sdk/storage/reference.py                                              |     8 |    0 |     8 |   100% |
| application_sdk/storage/transfer.py                                               |    12 |    2 |    10 |    83% |
| application_sdk/templates/__init__.py                                             |     1 |    0 |     1 |   100% |
| application_sdk/templates/base_metadata_extractor.py                              |     3 |    0 |     3 |   100% |
| application_sdk/templates/entity.py                                               |     2 |    0 |     2 |   100% |
| application_sdk/templates/incremental_sql_metadata_extractor.py                   |    17 |    0 |    17 |   100% |
| application_sdk/templates/sql_metadata_extractor.py                               |    11 |    0 |    11 |   100% |
| application_sdk/templates/sql_query_extractor.py                                  |     8 |    0 |     8 |   100% |
| application_sdk/templates/contracts/__init__.py                                   |     1 |    0 |     1 |   100% |
| application_sdk/templates/contracts/base_metadata_extraction.py                   |     3 |    0 |     3 |   100% |
| application_sdk/templates/contracts/incremental_sql.py                            |    20 |    0 |    20 |   100% |
| application_sdk/templates/contracts/sql_metadata.py                               |    18 |    0 |    18 |   100% |
| application_sdk/templates/contracts/sql_query.py                                  |     7 |    0 |     7 |   100% |
| application_sdk/test_utils/__init__.py                                            |     1 |    1 |     0 |     0% |
| application_sdk/test_utils/credentials.py                                         |     1 |    1 |     0 |     0% |
| application_sdk/test_utils/e2e/__init__.py                                        |    14 |    2 |    12 |    86% |
| application_sdk/test_utils/e2e/base.py                                            |    16 |    2 |    14 |    88% |
| application_sdk/test_utils/e2e/client.py                                          |    10 |    2 |     8 |    80% |
| application_sdk/test_utils/e2e/conftest.py                                        |     1 |    1 |     0 |     0% |
| application_sdk/test_utils/e2e/utils.py                                           |     3 |    1 |     2 |    67% |
| application_sdk/test_utils/hypothesis/__init__.py                                 |     1 |    1 |     0 |     0% |
| application_sdk/test_utils/hypothesis/strategies/__init__.py                      |     1 |    1 |     0 |     0% |
| application_sdk/test_utils/hypothesis/strategies/sql_client.py                    |     1 |    1 |     0 |     0% |
| application_sdk/test_utils/hypothesis/strategies/clients/__init__.py              |     1 |    1 |     0 |     0% |
| application_sdk/test_utils/hypothesis/strategies/clients/sql.py                   |     1 |    1 |     0 |     0% |
| application_sdk/test_utils/hypothesis/strategies/common/__init__.py               |     1 |    1 |     0 |     0% |
| application_sdk/test_utils/hypothesis/strategies/common/logger.py                 |     3 |    0 |     3 |   100% |
| application_sdk/test_utils/hypothesis/strategies/handlers/__init__.py             |     1 |    1 |     0 |     0% |
| application_sdk/test_utils/hypothesis/strategies/handlers/sql/__init__.py         |     1 |    1 |     0 |     0% |
| application_sdk/test_utils/hypothesis/strategies/handlers/sql/sql_metadata.py     |     1 |    1 |     0 |     0% |
| application_sdk/test_utils/hypothesis/strategies/handlers/sql/sql_preflight.py    |     1 |    1 |     0 |     0% |
| application_sdk/test_utils/hypothesis/strategies/inputs/__init__.py               |     1 |    1 |     0 |     0% |
| application_sdk/test_utils/hypothesis/strategies/inputs/json_input.py             |     1 |    1 |     0 |     0% |
| application_sdk/test_utils/hypothesis/strategies/inputs/parquet_input.py          |     1 |    1 |     0 |     0% |
| application_sdk/test_utils/hypothesis/strategies/outputs/__init__.py              |     1 |    1 |     0 |     0% |
| application_sdk/test_utils/hypothesis/strategies/outputs/json_output.py           |     2 |    1 |     1 |    50% |
| application_sdk/test_utils/hypothesis/strategies/outputs/statestore.py            |     3 |    1 |     2 |    67% |
| application_sdk/test_utils/hypothesis/strategies/server/__init__.py               |     1 |    1 |     0 |     0% |
| application_sdk/test_utils/hypothesis/strategies/server/fastapi/__init__.py       |     1 |    1 |     0 |     0% |
| application_sdk/test_utils/scale_data_generator/__init__.py                       |     1 |    1 |     0 |     0% |
| application_sdk/test_utils/scale_data_generator/config_loader.py                  |    10 |    4 |     6 |    60% |
| application_sdk/test_utils/scale_data_generator/data_generator.py                 |    10 |    3 |     7 |    70% |
| application_sdk/test_utils/scale_data_generator/driver.py                         |     3 |    3 |     0 |     0% |
| application_sdk/test_utils/scale_data_generator/output_handler/__init__.py        |     1 |    1 |     0 |     0% |
| application_sdk/test_utils/scale_data_generator/output_handler/base.py            |     7 |    3 |     4 |    57% |
| application_sdk/test_utils/scale_data_generator/output_handler/csv_handler.py     |     5 |    5 |     0 |     0% |
| application_sdk/test_utils/scale_data_generator/output_handler/json_handler.py    |     5 |    5 |     0 |     0% |
| application_sdk/test_utils/scale_data_generator/output_handler/parquet_handler.py |     6 |    6 |     0 |     0% |
| application_sdk/testing/__init__.py                                               |     1 |    0 |     1 |   100% |
| application_sdk/testing/fixtures.py                                               |    10 |    0 |    10 |   100% |
| application_sdk/testing/mocks.py                                                  |    51 |   14 |    37 |    73% |
| application_sdk/testing/e2e/__init__.py                                           |     1 |    0 |     1 |   100% |
| application_sdk/testing/e2e/config.py                                             |     2 |    0 |     2 |   100% |
| application_sdk/testing/e2e/deployer.py                                           |    11 |    1 |    10 |    91% |
| application_sdk/testing/e2e/logs.py                                               |     6 |    1 |     5 |    83% |
| application_sdk/testing/e2e/pods.py                                               |     5 |    1 |     4 |    80% |
| application_sdk/testing/e2e/portforward.py                                        |     4 |    0 |     4 |   100% |
| application_sdk/testing/e2e/workflows.py                                          |     3 |    0 |     3 |   100% |
| application_sdk/testing/scale_data_generator/__init__.py                          |     1 |    0 |     1 |   100% |
| application_sdk/testing/scale_data_generator/config_loader.py                     |    10 |    4 |     6 |    60% |
| application_sdk/testing/scale_data_generator/data_generator.py                    |    10 |    3 |     7 |    70% |
| application_sdk/testing/scale_data_generator/driver.py                            |     3 |    3 |     0 |     0% |
| application_sdk/testing/scale_data_generator/output_handler/__init__.py           |     1 |    1 |     0 |     0% |
| application_sdk/testing/scale_data_generator/output_handler/base.py               |     7 |    3 |     4 |    57% |
| application_sdk/testing/scale_data_generator/output_handler/csv_handler.py        |     5 |    5 |     0 |     0% |
| application_sdk/testing/scale_data_generator/output_handler/json_handler.py       |     5 |    5 |     0 |     0% |
| application_sdk/testing/scale_data_generator/output_handler/parquet_handler.py    |     6 |    6 |     0 |     0% |
| application_sdk/transformers/__init__.py                                          |     3 |    1 |     2 |    67% |
| application_sdk/transformers/atlas/__init__.py                                    |     6 |    1 |     5 |    83% |
| application_sdk/transformers/atlas/sql.py                                         |    25 |    4 |    21 |    84% |
| application_sdk/transformers/common/__init__.py                                   |     1 |    1 |     0 |     0% |
| application_sdk/transformers/common/utils.py                                      |     6 |    0 |     6 |   100% |
| application_sdk/transformers/query/__init__.py                                    |    11 |    2 |     9 |    82% |
| application_sdk/workflows/__init__.py                                             |     4 |    0 |     4 |   100% |
| application_sdk/workflows/metadata_extraction/__init__.py                         |     3 |    1 |     2 |    67% |
| application_sdk/workflows/metadata_extraction/incremental_sql.py                  |     5 |    0 |     5 |   100% |
| application_sdk/workflows/metadata_extraction/sql.py                              |     7 |    0 |     7 |   100% |
| application_sdk/workflows/outputs/__init__.py                                     |     2 |    0 |     2 |   100% |
| application_sdk/workflows/outputs/collector.py                                    |     9 |    0 |     9 |   100% |
| application_sdk/workflows/outputs/models.py                                       |     3 |    0 |     3 |   100% |
| application_sdk/workflows/query_extraction/__init__.py                            |     2 |    2 |     0 |     0% |
| application_sdk/workflows/query_extraction/sql.py                                 |     4 |    0 |     4 |   100% |
| examples/application_custom_fastapi.py                                            |    10 |    5 |     5 |    50% |
| examples/application_fastapi.py                                                   |    10 |    1 |     9 |    90% |
| examples/application_hello_world.py                                               |     6 |    0 |     6 |   100% |
| examples/application_sql.py                                                       |    11 |    3 |     8 |    73% |
| examples/application_sql_miner.py                                                 |     9 |    3 |     6 |    67% |
| examples/application_sql_with_custom_transformer.py                               |    12 |    7 |     5 |    42% |
| tests/__init__.py                                                                 |     1 |    1 |     0 |     0% |
| tests/conftest.py                                                                 |     1 |    0 |     1 |   100% |
| tests/e2e/__init__.py                                                             |     1 |    1 |     0 |     0% |
| tests/e2e/conftest.py                                                             |     5 |    1 |     4 |    80% |
| tests/integration/__init__.py                                                     |     1 |    1 |     0 |     0% |
| tests/integration/conftest.py                                                     |    10 |    2 |     8 |    80% |
| tests/integration/test_core_execution.py                                          |    29 |   24 |     5 |    17% |
| tests/integration/test_error_and_retry.py                                         |    19 |   15 |     4 |    21% |
| tests/integration/test_events_serde.py                                            |    15 |    5 |    10 |    67% |
| tests/integration/test_handler_service.py                                         |    39 |   19 |    20 |    51% |
| tests/integration/test_heartbeat.py                                               |    13 |   10 |     3 |    23% |
| tests/integration/test_lifecycle.py                                               |    21 |   17 |     4 |    19% |
| tests/integration/test_timeout.py                                                 |     7 |    5 |     2 |    29% |
| tests/unit/__init__.py                                                            |     1 |    1 |     0 |     0% |
| tests/unit/conftest.py                                                            |     5 |    1 |     4 |    80% |
| tests/unit/test_discovery.py                                                      |    75 |   69 |     6 |     8% |
| tests/unit/test_main.py                                                           |    60 |   48 |    12 |    20% |
| tests/unit/test_worker.py                                                         |    28 |    8 |    20 |    71% |
| tests/unit/activities/__init__.py                                                 |     1 |    1 |     0 |     0% |
| tests/unit/activities/test_activities.py                                          |    41 |    3 |    38 |    93% |
| tests/unit/activities/test_base_metadata_extraction_activities.py                 |     7 |    0 |     7 |   100% |
| tests/unit/activities/test_connection_normalization.py                            |    25 |    7 |    18 |    72% |
| tests/unit/activities/test_lock_management.py                                     |    12 |    0 |    12 |   100% |
| tests/unit/activities/common/__init__.py                                          |     1 |    1 |     0 |     0% |
| tests/unit/activities/common/test_sql_utils.py                                    |     4 |    1 |     3 |    75% |
| tests/unit/activities/common/test_utils.py                                        |    39 |   13 |    26 |    67% |
| tests/unit/activities/metadata_extraction/__init__.py                             |     1 |    1 |     0 |     0% |
| tests/unit/activities/metadata_extraction/test_credential_loading.py              |    14 |    4 |    10 |    71% |
| tests/unit/activities/metadata_extraction/test_sql.py                             |    56 |   38 |    18 |    32% |
| tests/unit/activities/query_extraction/__init__.py                                |     1 |    1 |     0 |     0% |
| tests/unit/app/__init__.py                                                        |     1 |    1 |     0 |     0% |
| tests/unit/app/test_base.py                                                       |    58 |   31 |    27 |    47% |
| tests/unit/app/test_cleanup_files.py                                              |    15 |   14 |     1 |     7% |
| tests/unit/app/test_cleanup_storage.py                                            |    29 |   26 |     3 |    10% |
| tests/unit/app/test_on_complete.py                                                |    35 |   32 |     3 |     9% |
| tests/unit/app/test_registry.py                                                   |    34 |    4 |    30 |    88% |
| tests/unit/app/test_task.py                                                       |    76 |   46 |    30 |    39% |
| tests/unit/application/__init__.py                                                |     1 |    1 |     0 |     0% |
| tests/unit/application/test_application.py                                        |    44 |    3 |    41 |    93% |
| tests/unit/application/test_manifest.py                                           |    15 |    3 |    12 |    80% |
| tests/unit/application/metadata_extraction/test_sql.py                            |    36 |    6 |    30 |    83% |
| tests/unit/clients/__init__.py                                                    |     1 |    1 |     0 |     0% |
| tests/unit/clients/test_async_sql_client.py                                       |    15 |   14 |     1 |     7% |
| tests/unit/clients/test_atlan_auth.py                                             |    11 |    0 |    11 |   100% |
| tests/unit/clients/test_atlan_client.py                                           |     7 |    7 |     0 |     0% |
| tests/unit/clients/test_atlanauth.py                                              |    11 |    1 |    10 |    91% |
| tests/unit/clients/test_azure_auth.py                                             |    14 |    0 |    14 |   100% |
| tests/unit/clients/test_azure_client.py                                           |    19 |    0 |    19 |   100% |
| tests/unit/clients/test_base_client.py                                            |    23 |    1 |    22 |    96% |
| tests/unit/clients/test_redis_client.py                                           |    40 |    0 |    40 |   100% |
| tests/unit/clients/test_sql_client.py                                             |    29 |    6 |    23 |    79% |
| tests/unit/clients/test_temporal_client.py                                        |    24 |    4 |    20 |    83% |
| tests/unit/common/test_aws_utils.py                                               |    30 |    1 |    29 |    97% |
| tests/unit/common/test_column_extraction.py                                       |    10 |    0 |    10 |   100% |
| tests/unit/common/test_credential_utils.py                                        |    30 |    1 |    29 |    97% |
| tests/unit/common/test_file_converter.py                                          |    29 |    0 |    29 |   100% |
| tests/unit/common/test_file_ops.py                                                |    21 |    0 |    21 |   100% |
| tests/unit/common/test_path.py                                                    |     6 |    0 |     6 |   100% |
| tests/unit/common/test_utils.py                                                   |    74 |    6 |    68 |    92% |
| tests/unit/common/test_utils_file_discovery.py                                    |    13 |    0 |    13 |   100% |
| tests/unit/common/incremental/__init__.py                                         |     1 |    1 |     0 |     0% |
| tests/unit/common/incremental/test_helpers.py                                     |    35 |    0 |    35 |   100% |
| tests/unit/common/incremental/test_marker.py                                      |    16 |    0 |    16 |   100% |
| tests/unit/common/incremental/test_models.py                                      |    15 |    0 |    15 |   100% |
| tests/unit/common/incremental/test_state_reader.py                                |     7 |    1 |     6 |    86% |
| tests/unit/common/incremental/test_state_writer.py                                |    21 |    0 |    21 |   100% |
| tests/unit/contracts/__init__.py                                                  |     1 |    1 |     0 |     0% |
| tests/unit/contracts/test_base.py                                                 |   112 |  111 |     1 |     1% |
| tests/unit/contracts/test_connection_ref.py                                       |    31 |   29 |     2 |     6% |
| tests/unit/contracts/test_git_reference.py                                        |    23 |   22 |     1 |     4% |
| tests/unit/contracts/test_storage_tier_temporal_serde.py                          |     9 |    1 |     8 |    89% |
| tests/unit/contracts/test_types.py                                                |    18 |   17 |     1 |     6% |
| tests/unit/credentials/__init__.py                                                |     1 |    1 |     0 |     0% |
| tests/unit/credentials/test_atlan_client.py                                       |    14 |    8 |     6 |    43% |
| tests/unit/credentials/test_mock_store.py                                         |    17 |   15 |     2 |    12% |
| tests/unit/credentials/test_oauth.py                                              |    19 |   15 |     4 |    21% |
| tests/unit/credentials/test_ref.py                                                |    16 |   14 |     2 |    12% |
| tests/unit/credentials/test_registry.py                                           |    20 |   18 |     2 |    10% |
| tests/unit/credentials/test_resolver.py                                           |    28 |   19 |     9 |    32% |
| tests/unit/credentials/test_types.py                                              |    42 |   41 |     1 |     2% |
| tests/unit/decorators/__init__.py                                                 |     1 |    1 |     0 |     0% |
| tests/unit/decorators/test_mcp_tool.py                                            |    56 |    4 |    52 |    93% |
| tests/unit/execution/__init__.py                                                  |     1 |    1 |     0 |     0% |
| tests/unit/execution/conftest.py                                                  |     4 |    2 |     2 |    50% |
| tests/unit/execution/test_activities.py                                           |    99 |   90 |     9 |     9% |
| tests/unit/execution/test_activities_tracking.py                                  |    18 |   12 |     6 |    33% |
| tests/unit/execution/test_converter.py                                            |    15 |   12 |     3 |    20% |
| tests/unit/execution/test_execution_context_interceptor.py                        |    10 |    1 |     9 |    90% |
| tests/unit/execution/test_settings.py                                             |    30 |   25 |     5 |    17% |
| tests/unit/execution/test_worker.py                                               |    42 |   36 |     6 |    14% |
| tests/unit/execution/test_workflows.py                                            |    19 |   17 |     2 |    11% |
| tests/unit/handler/__init__.py                                                    |     1 |    1 |     0 |     0% |
| tests/unit/handler/test_base.py                                                   |    18 |   17 |     1 |     6% |
| tests/unit/handler/test_contracts.py                                              |    35 |   29 |     6 |    17% |
| tests/unit/handler/test_service.py                                                |    97 |   67 |    30 |    31% |
| tests/unit/handlers/__init__.py                                                   |     1 |    1 |     0 |     0% |
| tests/unit/handlers/test_base_handler.py                                          |    26 |    2 |    24 |    92% |
| tests/unit/handlers/test_handler_configmap.py                                     |    11 |    0 |    11 |   100% |
| tests/unit/handlers/sql/test_auth.py                                              |    10 |    4 |     6 |    60% |
| tests/unit/handlers/sql/test_check_schemas_and_databases.py                       |    14 |    4 |    10 |    71% |
| tests/unit/handlers/sql/test_extract_allowed_schemas.py                           |    11 |    3 |     8 |    73% |
| tests/unit/handlers/sql/test_metadata.py                                          |    27 |   10 |    17 |    63% |
| tests/unit/handlers/sql/test_preflight_check.py                                   |    16 |   15 |     1 |     6% |
| tests/unit/handlers/sql/test_prepare_metadata.py                                  |    14 |    4 |    10 |    71% |
| tests/unit/handlers/sql/test_tables_check.py                                      |     9 |    6 |     3 |    33% |
| tests/unit/handlers/sql/test_validate_filters.py                                  |    12 |    4 |     8 |    67% |
| tests/unit/infrastructure/__init__.py                                             |     1 |    1 |     0 |     0% |
| tests/unit/infrastructure/test_bindings.py                                        |    18 |   14 |     4 |    22% |
| tests/unit/infrastructure/test_capacity.py                                        |    20 |   16 |     4 |    20% |
| tests/unit/infrastructure/test_pubsub.py                                          |    30 |   10 |    20 |    67% |
| tests/unit/infrastructure/test_secrets.py                                         |    30 |    0 |    30 |   100% |
| tests/unit/infrastructure/test_state.py                                           |    20 |    0 |    20 |   100% |
| tests/unit/interceptors/__init__.py                                               |     1 |    1 |     0 |     0% |
| tests/unit/interceptors/test_activity_failure_logging.py                          |    27 |    1 |    26 |    96% |
| tests/unit/interceptors/test_cleanup.py                                           |    14 |    9 |     5 |    36% |
| tests/unit/interceptors/test_correlation_context.py                               |    44 |    0 |    44 |   100% |
| tests/unit/interceptors/test_events.py                                            |    15 |   11 |     4 |    27% |
| tests/unit/io/test_base_io.py                                                     |    31 |    3 |    28 |    90% |
| tests/unit/io/test_writer_data_integrity.py                                       |    12 |    5 |     7 |    58% |
| tests/unit/io/readers/test_json_reader.py                                         |    38 |   19 |    19 |    50% |
| tests/unit/io/readers/test_parquet_reader.py                                      |    60 |   38 |    22 |    37% |
| tests/unit/io/writers/test_json_writer.py                                         |     7 |    6 |     1 |    14% |
| tests/unit/io/writers/test_parquet_writer.py                                      |    62 |   10 |    52 |    84% |
| tests/unit/observability/__init__.py                                              |     1 |    1 |     0 |     0% |
| tests/unit/observability/test_execution_context.py                                |    11 |    0 |    11 |   100% |
| tests/unit/observability/test_logger_adaptor.py                                   |    57 |    4 |    53 |    93% |
| tests/unit/observability/test_metrics_adaptor.py                                  |    20 |    1 |    19 |    95% |
| tests/unit/observability/test_traces_adaptor.py                                   |    13 |    1 |    12 |    92% |
| tests/unit/server/__init__.py                                                     |     1 |    1 |     0 |     0% |
| tests/unit/server/test_health.py                                                  |    24 |   21 |     3 |    12% |
| tests/unit/server/fastapi/test_fastapi.py                                         |    77 |   27 |    50 |    65% |
| tests/unit/server/fastapi/test_fastapi_utils.py                                   |    34 |    0 |    34 |   100% |
| tests/unit/server/fastapi/test_manifest_and_configmaps.py                         |    17 |    7 |    10 |    59% |
| tests/unit/server/fastapi/routers/__init__.py                                     |     1 |    1 |     0 |     0% |
| tests/unit/server/fastapi/routers/server.py                                       |     1 |    1 |     0 |     0% |
| tests/unit/server/mcp/__init__.py                                                 |     1 |    1 |     0 |     0% |
| tests/unit/server/mcp/test_mcp_server.py                                          |    24 |    1 |    23 |    96% |
| tests/unit/server/mcp/test_mcp_server_v3.py                                       |    14 |    9 |     5 |    36% |
| tests/unit/services/test_atlan_storage.py                                         |    11 |    0 |    11 |   100% |
| tests/unit/services/test_eventstore.py                                            |    18 |    0 |    18 |   100% |
| tests/unit/services/test_objectstore.py                                           |    47 |    5 |    42 |    89% |
| tests/unit/services/test_statestore.py                                            |    14 |    0 |    14 |   100% |
| tests/unit/services/test_statestore_path_traversal.py                             |    23 |   17 |     6 |    26% |
| tests/unit/storage/__init__.py                                                    |     1 |    1 |     0 |     0% |
| tests/unit/storage/test_binding.py                                                |    13 |    6 |     7 |    54% |
| tests/unit/storage/test_file_ref_sync.py                                          |    25 |   21 |     4 |    16% |
| tests/unit/storage/test_ops.py                                                    |    36 |   32 |     4 |    11% |
| tests/unit/storage/test_transfer.py                                               |    35 |   31 |     4 |    11% |
| tests/unit/templates/__init__.py                                                  |     1 |    1 |     0 |     0% |
| tests/unit/templates/conftest.py                                                  |     2 |    0 |     2 |   100% |
| tests/unit/templates/test_base_metadata_extractor.py                              |    16 |   11 |     5 |    31% |
| tests/unit/templates/test_entity_registry.py                                      |    34 |   30 |     4 |    12% |
| tests/unit/templates/test_incremental_sql_metadata_extractor.py                   |    52 |   40 |    12 |    23% |
| tests/unit/templates/test_sql_metadata_extractor.py                               |    44 |   35 |     9 |    20% |
| tests/unit/templates/test_sql_query_extractor.py                                  |    15 |   12 |     3 |    20% |
| tests/unit/testing/__init__.py                                                    |     1 |    1 |     0 |     0% |
| tests/unit/testing/test_fixtures.py                                               |    16 |   15 |     1 |     6% |
| tests/unit/testing/test_mocks.py                                                  |    29 |   28 |     1 |     3% |
| tests/unit/testing/e2e/__init__.py                                                |     1 |    1 |     0 |     0% |
| tests/unit/testing/e2e/test_deployer.py                                           |    20 |   19 |     1 |     5% |
| tests/unit/testing/e2e/test_logs.py                                               |    10 |    8 |     2 |    20% |
| tests/unit/testing/e2e/test_portforward.py                                        |     7 |    1 |     6 |    86% |
| tests/unit/tools/__init__.py                                                      |     1 |    1 |     0 |     0% |
| tests/unit/tools/test_check_migration.py                                          |    57 |   44 |    13 |    23% |
| tests/unit/tools/test_codemod_roundtrip.py                                        |    32 |   31 |     1 |     3% |
| tests/unit/tools/test_extract_context.py                                          |    50 |   48 |     2 |     4% |
| tests/unit/tools/test_fingerprint.py                                              |    23 |   21 |     2 |     9% |
| tests/unit/tools/test_rewrite_imports.py                                          |    42 |   32 |    10 |    24% |
| tests/unit/tools/test_run_codemods.py                                             |    16 |   15 |     1 |     6% |
| tests/unit/tools/test_codemods/__init__.py                                        |     1 |    1 |     0 |     0% |
| tests/unit/tools/test_codemods/conftest.py                                        |     2 |    0 |     2 |   100% |
| tests/unit/tools/test_codemods/test_remove_activities_cls.py                      |    15 |   11 |     4 |    27% |
| tests/unit/tools/test_codemods/test_remove_decorators.py                          |    17 |   16 |     1 |     6% |
| tests/unit/tools/test_codemods/test_rewrite_activity_calls.py                     |    16 |   11 |     5 |    31% |
| tests/unit/tools/test_codemods/test_rewrite_entry_point.py                        |    19 |   16 |     3 |    16% |
| tests/unit/tools/test_codemods/test_rewrite_handlers.py                           |    13 |   12 |     1 |     8% |
| tests/unit/tools/test_codemods/test_rewrite_returns.py                            |    12 |   10 |     2 |    17% |
| tests/unit/tools/test_codemods/test_rewrite_signatures.py                         |    19 |   18 |     1 |     5% |
| tests/unit/transformers/__init__.py                                               |     1 |    1 |     0 |     0% |
| tests/unit/transformers/atlas/__init__.py                                         |     1 |    1 |     0 |     0% |
| tests/unit/transformers/atlas/test_column.py                                      |    17 |    6 |    11 |    65% |
| tests/unit/transformers/atlas/test_database.py                                    |     8 |    6 |     2 |    25% |
| tests/unit/transformers/atlas/test_function.py                                    |     9 |    5 |     4 |    44% |
| tests/unit/transformers/atlas/test_procedure.py                                   |     7 |    6 |     1 |    14% |
| tests/unit/transformers/atlas/test_schema.py                                      |     8 |    6 |     2 |    25% |
| tests/unit/transformers/atlas/test_table.py                                       |    13 |    6 |     7 |    54% |
| tests/unit/transformers/query/test_sql_transformer.py                             |    16 |    4 |    12 |    75% |
| tests/unit/transformers/query/test_sql_transformer_output_validation.py           |     5 |    2 |     3 |    60% |
| tests/unit/workflows/metadata_extraction/test_base_workflow.py                    |     7 |    0 |     7 |   100% |
| tests/unit/workflows/metadata_extraction/test_sql_output_paths.py                 |    10 |    0 |    10 |   100% |
| tests/unit/workflows/metadata_extraction/test_sql_workflow.py                     |     9 |    4 |     5 |    56% |
| tests/unit/workflows/query_extraction/__init__.py                                 |     1 |    1 |     0 |     0% |
| tests/unit/workflows/query_extraction/test_sql.py                                 |     8 |    3 |     5 |    62% |
| tools/migrate_v3/__init__.py                                                      |     1 |    0 |     1 |   100% |
| tools/migrate_v3/check_migration.py                                               |    11 |    6 |     5 |    45% |
| tools/migrate_v3/contract_mapping.py                                              |     3 |    1 |     2 |    67% |
| tools/migrate_v3/extract_context.py                                               |    21 |   16 |     5 |    24% |
| tools/migrate_v3/fingerprint.py                                                   |     3 |    1 |     2 |    67% |
| tools/migrate_v3/import_mapping.py                                                |     2 |    0 |     2 |   100% |
| tools/migrate_v3/rewrite_imports.py                                               |    19 |    8 |    11 |    58% |
| tools/migrate_v3/run_codemods.py                                                  |    14 |    5 |     9 |    64% |
| tools/migrate_v3/codemods/__init__.py                                             |    11 |    4 |     7 |    64% |
| tools/migrate_v3/codemods/remove_activities_cls.py                                |    12 |    7 |     5 |    42% |
| tools/migrate_v3/codemods/remove_decorators.py                                    |    11 |    8 |     3 |    27% |
| tools/migrate_v3/codemods/rewrite_activity_calls.py                               |     6 |    1 |     5 |    83% |
| tools/migrate_v3/codemods/rewrite_entry_point.py                                  |    10 |    3 |     7 |    70% |
| tools/migrate_v3/codemods/rewrite_handlers.py                                     |     8 |    5 |     3 |    38% |
| tools/migrate_v3/codemods/rewrite_returns.py                                      |     7 |    5 |     2 |    29% |
| tools/migrate_v3/codemods/rewrite_signatures.py                                   |     8 |    4 |     4 |    50% |
|-----------------------------------------------------------------------------------|-------|------|-------|--------|
| TOTAL                                                                             |  6295 | 2583 |  3712 |  59.0% |
---------------- RESULT: PASSED (minimum: 30.0%, actual: 59.0%) ----------------

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 13, 2026

📦 Trivy Vulnerability Scan Results

Schema Version Created At Artifact Type
2 2026-04-13T19:52:36.799849124Z . repository

Report Summary

Could not generate summary table (data length mismatch: 9 vs 8).

Scan Result Details

requirements.txt
uv.lock

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 13, 2026

📦 Trivy Secret Scan Results

Schema Version Created At Artifact Type
2 2026-04-13T19:52:48.824779076Z . repository

Report Summary

Could not generate summary table (data length mismatch: 9 vs 8).

Scan Result Details

requirements.txt
uv.lock

@atlan-ci
Copy link
Copy Markdown
Collaborator

atlan-ci commented Apr 13, 2026

☂️ Python Coverage

current status: ✅

Overall Coverage

Lines Covered Coverage Threshold Status
15184 10611 70% 0% 🟢

New Files

No new covered files...

Modified Files

No covered modified files...

updated for commit: 0f23de5 by action🐍

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 13, 2026

🛠 Full Test Coverage Report: https://k.atlan.dev/coverage/application-sdk/pr/1298

AtMrun added 4 commits April 13, 2026 17:28
…ults

The hardcoded field mapping silently dropped counts for custom entities
(e.g. stages, streams). Now any result key matching an ExtractionOutput
field gets populated automatically via model_fields introspection.
Replace manual asyncio.gather + run() override examples with the
declarative EntityDef approach. Add EntityDef fields reference table
and multi-phase Snowflake example.
Replace class-attribute SQL strings and super() delegation with
EntityDef declarations and proper @task implementations using the
actual BaseSQLClient API (load + run_query).
@AtMrun
Copy link
Copy Markdown
Collaborator Author

AtMrun commented Apr 13, 2026

Code Review

This PR introduces EntityDef, a frozen dataclass for declarative entity definitions, and replaces the hardcoded 4-entity asyncio.gather in SqlMetadataExtractor.run() with a phased orchestration system. Entities are grouped by phase and run concurrently within each phase, sequentially across phases. The change maintains full backward compatibility -- an empty entities list falls back to the original 4 default entities.

Confidence Score: 4/5

  • Well-structured refactoring that follows SDK conventions, uses proper exception handling (rewrap), logging (get_logger), and typing
  • Checked for: security (dynamic dispatch safety, credential handling), performance (asyncio patterns, resource management), standards compliance (coding, exceptions, logging, commits, documentation), and test coverage
  • Deducted one point for unused configuration fields on EntityDef that could mislead developers -- details in findings below
Important Files Changed
File Change Risk
application_sdk/templates/entity.py Added Low
application_sdk/templates/sql_metadata_extractor.py Modified Medium
tests/unit/templates/test_entity_registry.py Added Low
docs/guides/sql-application-guide.md Modified Low
examples/application_sql.py Modified Low

Change Flow

sequenceDiagram
    participant Caller as Caller (Temporal)
    participant SME as SqlMetadataExtractor.run()
    participant GE as _get_entities()
    participant FE as _fetch_entity()
    participant Task as fetch_{name}() @task

    Caller->>SME: ExtractionInput
    SME->>GE: get enabled entities
    GE-->>SME: list[EntityDef]
    Note over SME: Group entities by phase
    loop For each phase (sorted)
        SME->>FE: asyncio.gather(*entities_in_phase)
        FE->>Task: dispatch to fetch_{name}(task_input)
        Task-->>FE: (result_key, count)
        FE-->>SME: phase results
    end
    SME->>SME: upload_to_atlan()
    SME-->>Caller: ExtractionOutput
Loading

Findings

# Severity File Issue
1 Warning application_sdk/templates/entity.py:L87 EntityDef.timeout_seconds is declared and documented as "Task timeout for this entity's extraction" but is never consumed by _fetch_entity() or the orchestration logic. The actual timeout is controlled exclusively by the @task(timeout_seconds=...) decorator on each fetch_* method. A developer setting EntityDef(name="columns", timeout_seconds=3600) would expect a 60-minute timeout but would silently get the 30-minute default from @task.
2 Info application_sdk/templates/entity.py:L41-L58 EntityDef fields sql, endpoint, pagination, and response_items_key are declared with documentation implying they drive fetch behavior, but _fetch_entity() does not pass the EntityDef to the dispatched method. The fetch method receives only ExtractionTaskInput, so it cannot access these fields. Currently only the "custom method" path (leave both empty, implement fetch_{name}()) is functional. Consider either wiring these fields into the dispatch or marking them as reserved/future in the docstring.

AtMrun added 2 commits April 13, 2026 17:44
Refactors SqlQueryExtractor to use the same entity-driven pattern as
SqlMetadataExtractor. The "queries" entity handles batching internally
(get_query_batches → fetch_queries per batch). Custom entities dispatch
to fetch_{name}() by convention.

Prepares for future Option A where queries can be declared as an entity
in SqlMetadataExtractor alongside metadata entities.
…tration

Replace super() delegation with EntityDef declaration and proper @task
implementations using the actual BaseSQLClient API.
@cmgrote cmgrote mentioned this pull request Apr 13, 2026
5 tasks
Copy link
Copy Markdown
Member

@Aryamanz29 Aryamanz29 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review: EntityDef and Entity-Driven Orchestration

Overview

Replaces hardcoded asyncio.gather of 4 entities in SqlMetadataExtractor.run() with a declarative EntityDef dataclass and phase-based orchestration. Also applies the same pattern to SqlQueryExtractor. Good design direction — reduces boilerplate for connectors with more than 4 entity types.

Strengths

  • EntityDef is clean — frozen dataclass, well-documented fields, sensible defaults
  • Phase grouping works well — concurrent within phase, sequential across phases
  • Backward compatible — empty entities list falls back to the default 4
  • Good test coverage — 17 new tests for EntityDef, _get_entities, _fetch_entity, phase grouping

Issues

1. Duplicated orchestration logic (Major)

SqlMetadataExtractor.run() and SqlQueryExtractor.run() have nearly identical phase-grouping and execution code:

phases: dict[int, list[EntityDef]] = {}
for entity in entities:
    phases.setdefault(entity.phase, []).append(entity)
for phase_num in sorted(phases):
    phase_results = await asyncio.gather(...)

This should be extracted into a shared method on BaseMetadataExtractor or a standalone function to avoid drift between the two.

2. _fetch_entity has different signatures (Medium)

  • SqlMetadataExtractor._fetch_entity(self, entity, base_input) — 2 args
  • SqlQueryExtractor._fetch_entity(self, entity, base_input, workflow_args) — 3 args

The query extractor needs workflow_args for the batch loop, but this breaks the uniform interface. Consider passing workflow_args through the QueryExtractionInput model instead, so both _fetch_entity methods have the same signature.

3. depends_on is declared but not implemented (Minor)

EntityDef.depends_on is documented as "Not yet implemented in orchestration — reserved for future use." This is fine for now, but it means the phase-based grouping is the only ordering mechanism. Just ensure it's tracked for future work.

4. Dynamic **entity_counts in output construction (Minor)

output_fields = ExtractionOutput.model_fields
entity_counts = {k: v for k, v in results.items() if k in output_fields}
return ExtractionOutput(**entity_counts, ...)

This silently drops result keys that don't match ExtractionOutput fields. If a connector defines EntityDef(name="stages"), the result stages_extracted won't appear in the output unless ExtractionOutput has that field. Consider logging a warning when result keys are dropped, or document that connectors must extend ExtractionOutput for custom entities.

5. EntityDef.sql and EntityDef.endpoint are unused (Minor)

These fields are declared on EntityDef but never read by the orchestration logic. The _fetch_entity method dispatches to fetch_{name}() regardless of whether sql or endpoint is set. Either:

  • Wire them into the dispatch (e.g. auto-generate SQL fetch when sql is set)
  • Or remove them and let subclasses handle fetch strategy in their fetch_* methods

If keeping them as documentation-only hints, note that in the docstring.

6. Missing error handling for individual entity failures

If one entity in a phase fails, asyncio.gather raises immediately and cancels sibling tasks. Consider return_exceptions=True to let other entities in the phase complete, then report the failures together.

Nitpicks

  • The SQL example removes the transform step entirely — the guide should clarify that transform_data is still available and called after all entities complete
  • QueryExtractionOutput uses total_queries as result key but QueryExtractionOutput.model_fields may not have that key — verify the mapping works

Verdict

Good direction. The duplicated orchestration code (issue #1) is the main thing to fix before merge.

Comment thread examples/application_sql.py Outdated
Comment thread examples/application_sql.py Outdated
Comment thread application_sdk/templates/entity.py Outdated
…ispatch, de-dup orchestration

- Rename EntityDef → ExtractableEntity (avoid Atlas typedef collision)
- Replace `name` field with `task_name` for explicit method mapping
- Remove unused fields: sql, endpoint, pagination, response_items_key
- Extract shared `run_entity_phases()` to eliminate duplicated
  orchestration logic between SqlMetadataExtractor and SqlQueryExtractor
- Unify `_fetch_entity` signature to `(entity, base_input)` across both
  extractors; query extractor computes workflow_args internally
- Add `return_exceptions=True` to asyncio.gather so sibling entities
  complete before errors are raised
- Log warnings for result keys that don't match output model fields
- Update examples, tests (21 pass, +4 new), and docs
@cmgrote cmgrote added the do not merge don't merge the change label Apr 14, 2026
@cmgrote
Copy link
Copy Markdown
Collaborator

cmgrote commented Apr 14, 2026

Suggest we hold on this briefly until most other refactor-v3 PRs are merged.

Base automatically changed from refactor-v3 to main April 19, 2026 01:01
@Aryamanz29
Copy link
Copy Markdown
Member

Closing — labeled "do not merge". EntityDef feature is tracked separately. Branch preserved — reopen against main when ready.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

do not merge don't merge the change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants