Skip to content

Commit fb4c981

Browse files
authored
Merge pull request #687 from atlanhq/APP-7850
APP-7850 : Add CRUD on DQ rules (v1)
2 parents 7a03f61 + 045052d commit fb4c981

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+3972
-101
lines changed

docs/asset/alpha_dqrule.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
.. _alpha_dqrule:
2+
3+
alpha_DQRule
4+
============
5+
6+
.. module:: pyatlan.model.assets
7+
:no-index:
8+
9+
.. autoclass:: alpha_DQRule
10+
:members:

docs/asset/alpha_dqruletemplate.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
.. _alpha_dqruletemplate:
2+
3+
alpha_DQRuleTemplate
4+
====================
5+
6+
.. module:: pyatlan.model.assets
7+
:no-index:
8+
9+
.. autoclass:: alpha_DQRuleTemplate
10+
:members:

docs/assets.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,3 +366,5 @@ You can interact with all of the following different kinds of assets:
366366
asset/view
367367
asset/workflow
368368
asset/workflowrun
369+
asset/alpha_dqrule
370+
asset/alpha_dqruletemplate
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
# Copyright 2025 Atlan Pte. Ltd.
3+
from __future__ import annotations
4+
5+
import threading
6+
from typing import TYPE_CHECKING, Dict, Optional
7+
8+
from pyatlan.model.assets import Asset
9+
from pyatlan.model.fluent_search import FluentSearch
10+
11+
if TYPE_CHECKING:
12+
from pyatlan.client.atlan import AtlanClient
13+
14+
15+
class DQTemplateConfigCache:
16+
"""
17+
Lazily-loaded cache for DQ rule template configurations to avoid multiple API calls.
18+
"""
19+
20+
def __init__(self, client: AtlanClient):
21+
self.client: AtlanClient = client
22+
self._cache: Dict[str, Dict] = {}
23+
self._lock: threading.Lock = threading.Lock()
24+
self._initialized: bool = False
25+
26+
def get_template_config(self, rule_type: str) -> Optional[Dict]:
27+
"""
28+
Get template configuration for a specific rule type.
29+
30+
:param rule_type: The display name of the rule type
31+
:returns: Template configuration dict or None if not found
32+
"""
33+
if not self._initialized:
34+
self._refresh_cache()
35+
36+
return self._cache.get(rule_type)
37+
38+
def _refresh_cache(self) -> None:
39+
"""Refresh the cache by fetching all template configurations."""
40+
with self._lock:
41+
if self._initialized:
42+
return
43+
44+
try:
45+
from pyatlan.model.assets.core.alpha__d_q_rule_template import (
46+
alpha_DQRuleTemplate,
47+
)
48+
49+
request = (
50+
FluentSearch()
51+
.where(Asset.TYPE_NAME.eq(alpha_DQRuleTemplate.__name__))
52+
.include_on_results(alpha_DQRuleTemplate.NAME)
53+
.include_on_results(alpha_DQRuleTemplate.QUALIFIED_NAME)
54+
.include_on_results(alpha_DQRuleTemplate.DISPLAY_NAME)
55+
.include_on_results(
56+
alpha_DQRuleTemplate.ALPHADQ_RULE_TEMPLATE_DIMENSION
57+
)
58+
.include_on_results(
59+
alpha_DQRuleTemplate.ALPHADQ_RULE_TEMPLATE_CONFIG
60+
)
61+
).to_request()
62+
63+
results = self.client.asset.search(request)
64+
for result in results:
65+
template_config = {
66+
"name": result.name,
67+
"qualified_name": result.qualified_name,
68+
"display_name": result.display_name,
69+
"dimension": result.alpha_dq_rule_template_dimension, # type: ignore
70+
"config": result.alpha_dq_rule_template_config, # type: ignore
71+
}
72+
self._cache[result.display_name] = template_config # type: ignore
73+
74+
self._initialized = True
75+
except Exception:
76+
# If cache refresh fails, mark as initialized to prevent infinite retries
77+
self._initialized = True
78+
raise

pyatlan/client/atlan.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
from pyatlan.cache.atlan_tag_cache import AtlanTagCache
3434
from pyatlan.cache.connection_cache import ConnectionCache
3535
from pyatlan.cache.custom_metadata_cache import CustomMetadataCache
36+
from pyatlan.cache.dq_template_config_cache import DQTemplateConfigCache
3637
from pyatlan.cache.enum_cache import EnumCache
3738
from pyatlan.cache.group_cache import GroupCache
3839
from pyatlan.cache.role_cache import RoleCache
@@ -174,6 +175,9 @@ class AtlanClient(BaseSettings):
174175
_custom_metadata_cache: Optional[CustomMetadataCache] = PrivateAttr(default=None)
175176
_connection_cache: Optional[ConnectionCache] = PrivateAttr(default=None)
176177
_source_tag_cache: Optional[SourceTagCache] = PrivateAttr(default=None)
178+
_dq_template_config_cache: Optional[DQTemplateConfigCache] = PrivateAttr(
179+
default=None
180+
)
177181

178182
class Config:
179183
env_prefix = "atlan_"
@@ -347,6 +351,12 @@ def source_tag_cache(self) -> SourceTagCache:
347351
self._source_tag_cache = SourceTagCache(client=self)
348352
return self._source_tag_cache
349353

354+
@property
355+
def dq_template_config_cache(self) -> DQTemplateConfigCache:
356+
if self._dq_template_config_cache is None:
357+
self._dq_template_config_cache = DQTemplateConfigCache(client=self)
358+
return self._dq_template_config_cache
359+
350360
@classmethod
351361
def from_token_guid(cls, guid: str) -> AtlanClient:
352362
"""

pyatlan/errors.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -932,6 +932,13 @@ class ErrorCode(Enum):
932932
"Verify the API token provided is a valid username for that token.",
933933
NotFoundError,
934934
)
935+
DQ_RULE_NOT_FOUND = (
936+
404,
937+
"ATLAN-PYTHON-404-029",
938+
"DQ rule with type {0} was not found.",
939+
"Verify you have provided a valid DQ rule type.",
940+
NotFoundError,
941+
)
935942
CONFLICT_PASSTHROUGH = (
936943
409,
937944
"ATLAN-PYTHON-409-000",

pyatlan/generator/class_generator.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ class AssetInfo:
227227
"DataProduct",
228228
"Referenceable",
229229
"Purpose",
230+
"alpha_DQRule",
230231
}
231232
_CORE_ASSETS = {
232233
"Referenceable",

0 commit comments

Comments
 (0)