acryl-datahub-cloud 0.3.11rc0__py3-none-any.whl → 0.3.16.1rc0__py3-none-any.whl
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.
Potentially problematic release.
This version of acryl-datahub-cloud might be problematic. Click here for more details.
- acryl_datahub_cloud/_codegen_config.json +1 -1
- acryl_datahub_cloud/acryl_cs_issues/models.py +5 -3
- acryl_datahub_cloud/action_request/action_request_owner_source.py +36 -6
- acryl_datahub_cloud/datahub_forms_notifications/__init__.py +0 -0
- acryl_datahub_cloud/datahub_forms_notifications/forms_notifications_source.py +569 -0
- acryl_datahub_cloud/datahub_forms_notifications/get_feature_flag.gql +7 -0
- acryl_datahub_cloud/datahub_forms_notifications/get_search_results_total.gql +14 -0
- acryl_datahub_cloud/datahub_forms_notifications/query.py +17 -0
- acryl_datahub_cloud/datahub_forms_notifications/scroll_forms_for_notification.gql +29 -0
- acryl_datahub_cloud/datahub_forms_notifications/send_form_notification_request.gql +5 -0
- acryl_datahub_cloud/datahub_reporting/datahub_dataset.py +37 -13
- acryl_datahub_cloud/datahub_reporting/datahub_form_reporting.py +55 -24
- acryl_datahub_cloud/datahub_reporting/extract_graph.py +4 -3
- acryl_datahub_cloud/datahub_reporting/extract_sql.py +242 -51
- acryl_datahub_cloud/datahub_reporting/forms.py +1 -1
- acryl_datahub_cloud/datahub_reporting/forms_config.py +3 -2
- acryl_datahub_cloud/datahub_restore/source.py +3 -2
- acryl_datahub_cloud/datahub_usage_reporting/excluded.py +94 -0
- acryl_datahub_cloud/datahub_usage_reporting/query_builder.py +48 -8
- acryl_datahub_cloud/datahub_usage_reporting/usage_feature_reporter.py +518 -77
- acryl_datahub_cloud/elasticsearch/graph_service.py +76 -14
- acryl_datahub_cloud/graphql_utils.py +64 -0
- acryl_datahub_cloud/lineage_features/source.py +555 -49
- acryl_datahub_cloud/metadata/_urns/urn_defs.py +2296 -1900
- acryl_datahub_cloud/metadata/com/linkedin/pegasus2avro/actionworkflow/__init__.py +53 -0
- acryl_datahub_cloud/metadata/com/linkedin/pegasus2avro/anomaly/__init__.py +2 -0
- acryl_datahub_cloud/metadata/com/linkedin/pegasus2avro/application/__init__.py +19 -0
- acryl_datahub_cloud/metadata/com/linkedin/pegasus2avro/assertion/__init__.py +4 -2
- acryl_datahub_cloud/metadata/com/linkedin/pegasus2avro/common/__init__.py +6 -0
- acryl_datahub_cloud/metadata/com/linkedin/pegasus2avro/conversation/__init__.py +29 -0
- acryl_datahub_cloud/metadata/com/linkedin/pegasus2avro/event/notification/settings/__init__.py +2 -0
- acryl_datahub_cloud/metadata/com/linkedin/pegasus2avro/execution/__init__.py +2 -0
- acryl_datahub_cloud/metadata/com/linkedin/pegasus2avro/file/__init__.py +19 -0
- acryl_datahub_cloud/metadata/com/linkedin/pegasus2avro/form/__init__.py +8 -0
- acryl_datahub_cloud/metadata/com/linkedin/pegasus2avro/identity/__init__.py +8 -0
- acryl_datahub_cloud/metadata/com/linkedin/pegasus2avro/knowledge/__init__.py +33 -0
- acryl_datahub_cloud/metadata/com/linkedin/pegasus2avro/logical/__init__.py +15 -0
- acryl_datahub_cloud/metadata/com/linkedin/pegasus2avro/metadata/key/__init__.py +12 -0
- acryl_datahub_cloud/metadata/com/linkedin/pegasus2avro/metadata/search/features/__init__.py +2 -0
- acryl_datahub_cloud/metadata/com/linkedin/pegasus2avro/module/__init__.py +31 -0
- acryl_datahub_cloud/metadata/com/linkedin/pegasus2avro/notification/__init__.py +19 -0
- acryl_datahub_cloud/metadata/com/linkedin/pegasus2avro/platform/event/v1/__init__.py +4 -0
- acryl_datahub_cloud/metadata/com/linkedin/pegasus2avro/role/__init__.py +2 -0
- acryl_datahub_cloud/metadata/com/linkedin/pegasus2avro/settings/asset/__init__.py +19 -0
- acryl_datahub_cloud/metadata/com/linkedin/pegasus2avro/settings/global/__init__.py +28 -0
- acryl_datahub_cloud/metadata/com/linkedin/pegasus2avro/template/__init__.py +31 -0
- acryl_datahub_cloud/metadata/schema.avsc +25091 -20557
- acryl_datahub_cloud/metadata/schema_classes.py +29269 -23863
- acryl_datahub_cloud/metadata/schemas/ActionRequestInfo.avsc +235 -2
- acryl_datahub_cloud/metadata/schemas/ActionWorkflowInfo.avsc +683 -0
- acryl_datahub_cloud/metadata/schemas/ActionWorkflowKey.avsc +21 -0
- acryl_datahub_cloud/metadata/schemas/Actors.avsc +38 -1
- acryl_datahub_cloud/metadata/schemas/ApplicationKey.avsc +31 -0
- acryl_datahub_cloud/metadata/schemas/ApplicationProperties.avsc +75 -0
- acryl_datahub_cloud/metadata/schemas/Applications.avsc +38 -0
- acryl_datahub_cloud/metadata/schemas/AssertionAnalyticsRunEvent.avsc +353 -215
- acryl_datahub_cloud/metadata/schemas/AssertionInfo.avsc +147 -20
- acryl_datahub_cloud/metadata/schemas/AssertionKey.avsc +1 -1
- acryl_datahub_cloud/metadata/schemas/AssertionRunEvent.avsc +166 -21
- acryl_datahub_cloud/metadata/schemas/{AssertionSummary.avsc → AssertionRunSummary.avsc} +15 -2
- acryl_datahub_cloud/metadata/schemas/AssertionsSummary.avsc +54 -0
- acryl_datahub_cloud/metadata/schemas/AssetSettings.avsc +63 -0
- acryl_datahub_cloud/metadata/schemas/BusinessAttributeInfo.avsc +7 -3
- acryl_datahub_cloud/metadata/schemas/ChartInfo.avsc +20 -6
- acryl_datahub_cloud/metadata/schemas/ChartKey.avsc +1 -0
- acryl_datahub_cloud/metadata/schemas/ConstraintInfo.avsc +12 -1
- acryl_datahub_cloud/metadata/schemas/ContainerKey.avsc +1 -0
- acryl_datahub_cloud/metadata/schemas/ContainerProperties.avsc +16 -5
- acryl_datahub_cloud/metadata/schemas/CorpGroupEditableInfo.avsc +2 -1
- acryl_datahub_cloud/metadata/schemas/CorpGroupInfo.avsc +7 -3
- acryl_datahub_cloud/metadata/schemas/CorpGroupKey.avsc +2 -1
- acryl_datahub_cloud/metadata/schemas/CorpGroupSettings.avsc +127 -2
- acryl_datahub_cloud/metadata/schemas/CorpUserEditableInfo.avsc +1 -1
- acryl_datahub_cloud/metadata/schemas/CorpUserInfo.avsc +18 -2
- acryl_datahub_cloud/metadata/schemas/CorpUserInvitationStatus.avsc +106 -0
- acryl_datahub_cloud/metadata/schemas/CorpUserKey.avsc +4 -1
- acryl_datahub_cloud/metadata/schemas/CorpUserSettings.avsc +304 -2
- acryl_datahub_cloud/metadata/schemas/CorpUserUsageFeatures.avsc +86 -0
- acryl_datahub_cloud/metadata/schemas/DashboardInfo.avsc +11 -5
- acryl_datahub_cloud/metadata/schemas/DashboardKey.avsc +1 -0
- acryl_datahub_cloud/metadata/schemas/DataFlowInfo.avsc +15 -5
- acryl_datahub_cloud/metadata/schemas/DataFlowKey.avsc +1 -0
- acryl_datahub_cloud/metadata/schemas/DataHubAiConversationInfo.avsc +256 -0
- acryl_datahub_cloud/metadata/schemas/DataHubAiConversationKey.avsc +22 -0
- acryl_datahub_cloud/metadata/schemas/DataHubFileInfo.avsc +234 -0
- acryl_datahub_cloud/metadata/schemas/DataHubFileKey.avsc +22 -0
- acryl_datahub_cloud/metadata/schemas/DataHubIngestionSourceKey.avsc +2 -1
- acryl_datahub_cloud/metadata/schemas/DataHubPageModuleKey.avsc +21 -0
- acryl_datahub_cloud/metadata/schemas/DataHubPageModuleProperties.avsc +308 -0
- acryl_datahub_cloud/metadata/schemas/DataHubPageTemplateKey.avsc +21 -0
- acryl_datahub_cloud/metadata/schemas/DataHubPageTemplateProperties.avsc +251 -0
- acryl_datahub_cloud/metadata/schemas/DataHubPolicyInfo.avsc +12 -1
- acryl_datahub_cloud/metadata/schemas/DataJobInfo.avsc +13 -4
- acryl_datahub_cloud/metadata/schemas/DataJobInputOutput.avsc +8 -0
- acryl_datahub_cloud/metadata/schemas/DataJobKey.avsc +1 -0
- acryl_datahub_cloud/metadata/schemas/DataPlatformInfo.avsc +3 -1
- acryl_datahub_cloud/metadata/schemas/DataPlatformInstanceProperties.avsc +5 -2
- acryl_datahub_cloud/metadata/schemas/DataProcessKey.avsc +4 -0
- acryl_datahub_cloud/metadata/schemas/DataProductKey.avsc +2 -0
- acryl_datahub_cloud/metadata/schemas/DataProductProperties.avsc +6 -3
- acryl_datahub_cloud/metadata/schemas/DataTypeInfo.avsc +5 -0
- acryl_datahub_cloud/metadata/schemas/DatasetKey.avsc +10 -2
- acryl_datahub_cloud/metadata/schemas/DatasetProperties.avsc +12 -5
- acryl_datahub_cloud/metadata/schemas/DatasetUsageStatistics.avsc +8 -0
- acryl_datahub_cloud/metadata/schemas/DocumentInfo.avsc +407 -0
- acryl_datahub_cloud/metadata/schemas/DocumentKey.avsc +35 -0
- acryl_datahub_cloud/metadata/schemas/DocumentSettings.avsc +79 -0
- acryl_datahub_cloud/metadata/schemas/DomainKey.avsc +2 -0
- acryl_datahub_cloud/metadata/schemas/DomainProperties.avsc +7 -3
- acryl_datahub_cloud/metadata/schemas/EditableContainerProperties.avsc +2 -1
- acryl_datahub_cloud/metadata/schemas/EditableDashboardProperties.avsc +2 -1
- acryl_datahub_cloud/metadata/schemas/EditableDataFlowProperties.avsc +2 -1
- acryl_datahub_cloud/metadata/schemas/EditableDataJobProperties.avsc +2 -1
- acryl_datahub_cloud/metadata/schemas/EditableDatasetProperties.avsc +2 -1
- acryl_datahub_cloud/metadata/schemas/EditableERModelRelationshipProperties.avsc +2 -1
- acryl_datahub_cloud/metadata/schemas/EditableMLFeatureProperties.avsc +2 -1
- acryl_datahub_cloud/metadata/schemas/EditableMLFeatureTableProperties.avsc +2 -1
- acryl_datahub_cloud/metadata/schemas/EditableMLModelGroupProperties.avsc +2 -1
- acryl_datahub_cloud/metadata/schemas/EditableMLModelProperties.avsc +2 -1
- acryl_datahub_cloud/metadata/schemas/EditableNotebookProperties.avsc +2 -1
- acryl_datahub_cloud/metadata/schemas/EditableSchemaMetadata.avsc +4 -2
- acryl_datahub_cloud/metadata/schemas/EntityTypeInfo.avsc +5 -0
- acryl_datahub_cloud/metadata/schemas/ExecutionRequestArtifactsLocation.avsc +16 -0
- acryl_datahub_cloud/metadata/schemas/ExecutionRequestKey.avsc +2 -1
- acryl_datahub_cloud/metadata/schemas/FormAssignmentStatus.avsc +36 -0
- acryl_datahub_cloud/metadata/schemas/FormInfo.avsc +6 -0
- acryl_datahub_cloud/metadata/schemas/FormKey.avsc +3 -1
- acryl_datahub_cloud/metadata/schemas/FormNotifications.avsc +69 -0
- acryl_datahub_cloud/metadata/schemas/FormSettings.avsc +30 -0
- acryl_datahub_cloud/metadata/schemas/GlobalSettingsInfo.avsc +416 -0
- acryl_datahub_cloud/metadata/schemas/GlobalTags.avsc +2 -1
- acryl_datahub_cloud/metadata/schemas/GlossaryNodeInfo.avsc +3 -1
- acryl_datahub_cloud/metadata/schemas/GlossaryNodeKey.avsc +1 -0
- acryl_datahub_cloud/metadata/schemas/GlossaryTermInfo.avsc +3 -1
- acryl_datahub_cloud/metadata/schemas/GlossaryTermKey.avsc +2 -0
- acryl_datahub_cloud/metadata/schemas/IcebergWarehouseInfo.avsc +4 -0
- acryl_datahub_cloud/metadata/schemas/IncidentActivityEvent.avsc +3 -3
- acryl_datahub_cloud/metadata/schemas/IncidentInfo.avsc +3 -3
- acryl_datahub_cloud/metadata/schemas/InferredMetadata.avsc +71 -1
- acryl_datahub_cloud/metadata/schemas/InputFields.avsc +2 -1
- acryl_datahub_cloud/metadata/schemas/InviteToken.avsc +26 -0
- acryl_datahub_cloud/metadata/schemas/LineageFeatures.avsc +67 -42
- acryl_datahub_cloud/metadata/schemas/LogicalParent.avsc +145 -0
- acryl_datahub_cloud/metadata/schemas/MLFeatureKey.avsc +4 -1
- acryl_datahub_cloud/metadata/schemas/MLFeatureTableKey.avsc +4 -1
- acryl_datahub_cloud/metadata/schemas/MLModelDeploymentKey.avsc +7 -1
- acryl_datahub_cloud/metadata/schemas/MLModelGroupKey.avsc +9 -1
- acryl_datahub_cloud/metadata/schemas/MLModelKey.avsc +9 -1
- acryl_datahub_cloud/metadata/schemas/MLModelProperties.avsc +4 -2
- acryl_datahub_cloud/metadata/schemas/MLPrimaryKeyKey.avsc +4 -1
- acryl_datahub_cloud/metadata/schemas/MetadataChangeEvent.avsc +418 -97
- acryl_datahub_cloud/metadata/schemas/MetadataChangeLog.avsc +62 -44
- acryl_datahub_cloud/metadata/schemas/MetadataChangeProposal.avsc +61 -0
- acryl_datahub_cloud/metadata/schemas/MonitorAnomalyEvent.avsc +54 -9
- acryl_datahub_cloud/metadata/schemas/MonitorInfo.avsc +163 -23
- acryl_datahub_cloud/metadata/schemas/MonitorKey.avsc +9 -1
- acryl_datahub_cloud/metadata/schemas/MonitorSuiteInfo.avsc +128 -3
- acryl_datahub_cloud/metadata/schemas/NotebookInfo.avsc +5 -2
- acryl_datahub_cloud/metadata/schemas/NotebookKey.avsc +1 -0
- acryl_datahub_cloud/metadata/schemas/NotificationRequest.avsc +91 -4
- acryl_datahub_cloud/metadata/schemas/Operation.avsc +17 -0
- acryl_datahub_cloud/metadata/schemas/Ownership.avsc +71 -1
- acryl_datahub_cloud/metadata/schemas/QuerySubjects.avsc +2 -13
- acryl_datahub_cloud/metadata/schemas/RelationshipChangeEvent.avsc +215 -0
- acryl_datahub_cloud/metadata/schemas/RoleProperties.avsc +3 -1
- acryl_datahub_cloud/metadata/schemas/SchemaFieldInfo.avsc +3 -1
- acryl_datahub_cloud/metadata/schemas/SchemaFieldKey.avsc +3 -0
- acryl_datahub_cloud/metadata/schemas/SchemaMetadata.avsc +2 -1
- acryl_datahub_cloud/metadata/schemas/SemanticContent.avsc +123 -0
- acryl_datahub_cloud/metadata/schemas/StructuredProperties.avsc +69 -0
- acryl_datahub_cloud/metadata/schemas/StructuredPropertyDefinition.avsc +15 -4
- acryl_datahub_cloud/metadata/schemas/StructuredPropertySettings.avsc +9 -0
- acryl_datahub_cloud/metadata/schemas/SubscriptionInfo.avsc +136 -5
- acryl_datahub_cloud/metadata/schemas/SubscriptionKey.avsc +2 -1
- acryl_datahub_cloud/metadata/schemas/SystemMetadata.avsc +61 -0
- acryl_datahub_cloud/metadata/schemas/TagProperties.avsc +3 -1
- acryl_datahub_cloud/metadata/schemas/TestInfo.avsc +2 -1
- acryl_datahub_cloud/metadata/schemas/UpstreamLineage.avsc +9 -0
- acryl_datahub_cloud/metadata/schemas/UsageFeatures.avsc +10 -0
- acryl_datahub_cloud/notifications/__init__.py +0 -0
- acryl_datahub_cloud/notifications/notification_recipient_builder.py +399 -0
- acryl_datahub_cloud/sdk/__init__.py +69 -0
- acryl_datahub_cloud/sdk/assertion/__init__.py +58 -0
- acryl_datahub_cloud/sdk/assertion/assertion_base.py +779 -0
- acryl_datahub_cloud/sdk/assertion/column_metric_assertion.py +191 -0
- acryl_datahub_cloud/sdk/assertion/column_value_assertion.py +431 -0
- acryl_datahub_cloud/sdk/assertion/freshness_assertion.py +201 -0
- acryl_datahub_cloud/sdk/assertion/schema_assertion.py +268 -0
- acryl_datahub_cloud/sdk/assertion/smart_column_metric_assertion.py +212 -0
- acryl_datahub_cloud/sdk/assertion/smart_freshness_assertion.py +165 -0
- acryl_datahub_cloud/sdk/assertion/smart_sql_assertion.py +156 -0
- acryl_datahub_cloud/sdk/assertion/smart_volume_assertion.py +162 -0
- acryl_datahub_cloud/sdk/assertion/sql_assertion.py +273 -0
- acryl_datahub_cloud/sdk/assertion/types.py +20 -0
- acryl_datahub_cloud/sdk/assertion/volume_assertion.py +156 -0
- acryl_datahub_cloud/sdk/assertion_client/__init__.py +0 -0
- acryl_datahub_cloud/sdk/assertion_client/column_metric.py +545 -0
- acryl_datahub_cloud/sdk/assertion_client/column_value.py +617 -0
- acryl_datahub_cloud/sdk/assertion_client/freshness.py +371 -0
- acryl_datahub_cloud/sdk/assertion_client/helpers.py +166 -0
- acryl_datahub_cloud/sdk/assertion_client/schema.py +358 -0
- acryl_datahub_cloud/sdk/assertion_client/smart_column_metric.py +540 -0
- acryl_datahub_cloud/sdk/assertion_client/smart_freshness.py +373 -0
- acryl_datahub_cloud/sdk/assertion_client/smart_sql.py +411 -0
- acryl_datahub_cloud/sdk/assertion_client/smart_volume.py +380 -0
- acryl_datahub_cloud/sdk/assertion_client/sql.py +410 -0
- acryl_datahub_cloud/sdk/assertion_client/volume.py +446 -0
- acryl_datahub_cloud/sdk/assertion_input/__init__.py +0 -0
- acryl_datahub_cloud/sdk/assertion_input/assertion_input.py +1470 -0
- acryl_datahub_cloud/sdk/assertion_input/column_assertion_constants.py +114 -0
- acryl_datahub_cloud/sdk/assertion_input/column_assertion_utils.py +284 -0
- acryl_datahub_cloud/sdk/assertion_input/column_metric_assertion_input.py +759 -0
- acryl_datahub_cloud/sdk/assertion_input/column_metric_constants.py +109 -0
- acryl_datahub_cloud/sdk/assertion_input/column_value_assertion_input.py +810 -0
- acryl_datahub_cloud/sdk/assertion_input/freshness_assertion_input.py +305 -0
- acryl_datahub_cloud/sdk/assertion_input/schema_assertion_input.py +413 -0
- acryl_datahub_cloud/sdk/assertion_input/smart_column_metric_assertion_input.py +793 -0
- acryl_datahub_cloud/sdk/assertion_input/smart_freshness_assertion_input.py +218 -0
- acryl_datahub_cloud/sdk/assertion_input/smart_sql_assertion_input.py +181 -0
- acryl_datahub_cloud/sdk/assertion_input/smart_volume_assertion_input.py +189 -0
- acryl_datahub_cloud/sdk/assertion_input/sql_assertion_input.py +320 -0
- acryl_datahub_cloud/sdk/assertion_input/volume_assertion_input.py +635 -0
- acryl_datahub_cloud/sdk/assertions_client.py +1074 -0
- acryl_datahub_cloud/sdk/entities/__init__.py +0 -0
- acryl_datahub_cloud/sdk/entities/assertion.py +439 -0
- acryl_datahub_cloud/sdk/entities/monitor.py +291 -0
- acryl_datahub_cloud/sdk/entities/subscription.py +100 -0
- acryl_datahub_cloud/sdk/errors.py +34 -0
- acryl_datahub_cloud/sdk/resolver_client.py +42 -0
- acryl_datahub_cloud/sdk/subscription_client.py +737 -0
- {acryl_datahub_cloud-0.3.11rc0.dist-info → acryl_datahub_cloud-0.3.16.1rc0.dist-info}/METADATA +55 -49
- {acryl_datahub_cloud-0.3.11rc0.dist-info → acryl_datahub_cloud-0.3.16.1rc0.dist-info}/RECORD +235 -142
- {acryl_datahub_cloud-0.3.11rc0.dist-info → acryl_datahub_cloud-0.3.16.1rc0.dist-info}/WHEEL +1 -1
- {acryl_datahub_cloud-0.3.11rc0.dist-info → acryl_datahub_cloud-0.3.16.1rc0.dist-info}/entry_points.txt +1 -0
- acryl_datahub_cloud/_sdk_extras/__init__.py +0 -4
- acryl_datahub_cloud/_sdk_extras/assertion.py +0 -15
- acryl_datahub_cloud/_sdk_extras/assertions_client.py +0 -23
- {acryl_datahub_cloud-0.3.11rc0.dist-info → acryl_datahub_cloud-0.3.16.1rc0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from typing import (
|
|
3
|
+
Any,
|
|
4
|
+
Dict,
|
|
5
|
+
Optional,
|
|
6
|
+
Tuple,
|
|
7
|
+
Type,
|
|
8
|
+
TypeAlias,
|
|
9
|
+
Union,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
from typing_extensions import (
|
|
13
|
+
Self,
|
|
14
|
+
assert_never,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
from datahub.emitter.enum_helpers import get_enum_options
|
|
18
|
+
from datahub.errors import SdkUsageError
|
|
19
|
+
from datahub.metadata import schema_classes as models
|
|
20
|
+
from datahub.metadata.urns import (
|
|
21
|
+
AssertionUrn,
|
|
22
|
+
DatasetUrn,
|
|
23
|
+
MonitorUrn,
|
|
24
|
+
Urn,
|
|
25
|
+
)
|
|
26
|
+
from datahub.sdk.entity import Entity
|
|
27
|
+
|
|
28
|
+
logger = logging.getLogger(__name__)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
MonitorIdentityInputType: TypeAlias = Union[
|
|
32
|
+
Tuple[DatasetUrn, str], # (dataset urn, monitor id)
|
|
33
|
+
models.MonitorKeyClass,
|
|
34
|
+
MonitorUrn,
|
|
35
|
+
Tuple[
|
|
36
|
+
DatasetUrn, AssertionUrn
|
|
37
|
+
], # (dataset urn, assertion urn - monitor id is got from assertion id)
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
MonitorInfoInputType: TypeAlias = Union[
|
|
41
|
+
Tuple[ # (monitor type [ASSERTION|FRESHNESS], monitor status mode [ACTIVE|INACTIVE|PASSIVE])
|
|
42
|
+
str, str
|
|
43
|
+
],
|
|
44
|
+
Tuple[ # (monitor type enum, monitor status mode enum)
|
|
45
|
+
models.MonitorTypeClass, models.MonitorModeClass
|
|
46
|
+
],
|
|
47
|
+
models.MonitorInfoClass,
|
|
48
|
+
]
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class Monitor(Entity):
|
|
52
|
+
"""
|
|
53
|
+
Monitor entity class.
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
__slots__ = ()
|
|
57
|
+
|
|
58
|
+
@classmethod
|
|
59
|
+
def get_urn_type(cls) -> Type[MonitorUrn]:
|
|
60
|
+
"""Get the URN type for monitors.
|
|
61
|
+
|
|
62
|
+
Returns:
|
|
63
|
+
The MonitorUrn class.
|
|
64
|
+
"""
|
|
65
|
+
return MonitorUrn
|
|
66
|
+
|
|
67
|
+
def __init__(
|
|
68
|
+
self,
|
|
69
|
+
id: MonitorIdentityInputType,
|
|
70
|
+
# MonitorInfo
|
|
71
|
+
info: MonitorInfoInputType,
|
|
72
|
+
external_url: Optional[str] = None,
|
|
73
|
+
custom_properties: Optional[Dict[str, str]] = None,
|
|
74
|
+
) -> None:
|
|
75
|
+
super().__init__(urn=Monitor._ensure_id(id=id))
|
|
76
|
+
|
|
77
|
+
self._set_info(info)
|
|
78
|
+
|
|
79
|
+
if external_url is not None:
|
|
80
|
+
# this may overwrite the value set from info#externalUrl value
|
|
81
|
+
self.set_external_url(external_url)
|
|
82
|
+
if custom_properties is not None:
|
|
83
|
+
# this may overwrite the value set from info#customPropperties value
|
|
84
|
+
self.set_custom_properties(custom_properties)
|
|
85
|
+
|
|
86
|
+
@classmethod
|
|
87
|
+
def _new_from_graph(cls, urn: Urn, current_aspects: models.AspectBag) -> Self:
|
|
88
|
+
assert isinstance(urn, MonitorUrn)
|
|
89
|
+
assert "monitorInfo" in current_aspects, "MonitorInfo is required"
|
|
90
|
+
|
|
91
|
+
entity = cls(id=urn, info=current_aspects["monitorInfo"])
|
|
92
|
+
return entity._init_from_graph(current_aspects)
|
|
93
|
+
|
|
94
|
+
@property
|
|
95
|
+
def urn(self) -> MonitorUrn:
|
|
96
|
+
assert isinstance(self._urn, MonitorUrn)
|
|
97
|
+
return self._urn
|
|
98
|
+
|
|
99
|
+
@classmethod
|
|
100
|
+
def _ensure_id(
|
|
101
|
+
cls,
|
|
102
|
+
id: MonitorIdentityInputType,
|
|
103
|
+
) -> MonitorUrn:
|
|
104
|
+
if isinstance(id, tuple):
|
|
105
|
+
if (
|
|
106
|
+
len(id) != 2
|
|
107
|
+
or not isinstance(id[0], DatasetUrn)
|
|
108
|
+
or not isinstance(id[1], (str, AssertionUrn))
|
|
109
|
+
):
|
|
110
|
+
raise SdkUsageError(
|
|
111
|
+
f"Invalid monitor identity input tuple: {id}. Expected a tuple of (dataset/entity urn, monitor id)."
|
|
112
|
+
)
|
|
113
|
+
if isinstance(id[1], str):
|
|
114
|
+
# If the second element is a string, we treat it as the monitor id.
|
|
115
|
+
# This allows for flexibility in how monitor ids are specified.
|
|
116
|
+
return MonitorUrn(entity=id[0], id=id[1])
|
|
117
|
+
elif isinstance(id[1], AssertionUrn):
|
|
118
|
+
# If the second element is an AssertionUrn, we use assertion urn as the monitor id so they both are linked.
|
|
119
|
+
return MonitorUrn(entity=id[0], id=id[1].urn())
|
|
120
|
+
else:
|
|
121
|
+
assert_never(id[1])
|
|
122
|
+
elif isinstance(id, models.MonitorKeyClass):
|
|
123
|
+
# This validation may look redundant but it is not.
|
|
124
|
+
# While MonitorKey PDL model ensures entity is a DatasetUrn,
|
|
125
|
+
# generated python code for entity's type in MonitorKeyClass is not so strict and allows for any string.
|
|
126
|
+
entity: DatasetUrn
|
|
127
|
+
if isinstance(id.entity, str):
|
|
128
|
+
try:
|
|
129
|
+
entity = DatasetUrn.from_string(id.entity)
|
|
130
|
+
except Exception as e:
|
|
131
|
+
raise SdkUsageError(
|
|
132
|
+
f"Invalid monitor identity input key: {id}. Invalid dataset urn for entity."
|
|
133
|
+
) from e
|
|
134
|
+
else:
|
|
135
|
+
if not isinstance(id.entity, DatasetUrn):
|
|
136
|
+
raise SdkUsageError(
|
|
137
|
+
f"Invalid monitor identity input key: {id}. Expected a DatasetUrn for entity."
|
|
138
|
+
)
|
|
139
|
+
entity = id.entity
|
|
140
|
+
return MonitorUrn(entity=entity, id=id.id)
|
|
141
|
+
elif isinstance(id, MonitorUrn):
|
|
142
|
+
return id
|
|
143
|
+
else:
|
|
144
|
+
assert_never(id)
|
|
145
|
+
|
|
146
|
+
def _ensure_info(self) -> models.MonitorInfoClass:
|
|
147
|
+
return self._setdefault_aspect(
|
|
148
|
+
models.MonitorInfoClass(
|
|
149
|
+
# TBC: just because we need to set them!
|
|
150
|
+
type=models.MonitorTypeClass.ASSERTION,
|
|
151
|
+
status=models.MonitorStatusClass(mode=models.MonitorModeClass.ACTIVE),
|
|
152
|
+
)
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
@property
|
|
156
|
+
def info(self) -> models.MonitorInfoClass:
|
|
157
|
+
"""Get the monitor info.
|
|
158
|
+
|
|
159
|
+
Returns:
|
|
160
|
+
The monitor info.
|
|
161
|
+
"""
|
|
162
|
+
return self._ensure_info()
|
|
163
|
+
|
|
164
|
+
def _set_info(self, info: MonitorInfoInputType) -> None:
|
|
165
|
+
"""Set the monitor info.
|
|
166
|
+
|
|
167
|
+
Args:
|
|
168
|
+
info: The monitor info.
|
|
169
|
+
"""
|
|
170
|
+
if isinstance(info, tuple):
|
|
171
|
+
if len(info) != 2:
|
|
172
|
+
raise SdkUsageError(
|
|
173
|
+
f"Invalid monitor info input tuple: {info}. Expected a tuple of (monitor type, monitor status)."
|
|
174
|
+
)
|
|
175
|
+
type, mode_status = info
|
|
176
|
+
if isinstance(type, str) and type not in get_enum_options(
|
|
177
|
+
models.MonitorTypeClass
|
|
178
|
+
):
|
|
179
|
+
raise SdkUsageError(
|
|
180
|
+
f"Invalid monitor type: {type}. Expected {get_enum_options(models.MonitorTypeClass)}."
|
|
181
|
+
)
|
|
182
|
+
if isinstance(mode_status, str) and mode_status not in get_enum_options(
|
|
183
|
+
models.MonitorModeClass
|
|
184
|
+
):
|
|
185
|
+
raise SdkUsageError(
|
|
186
|
+
f"Invalid monitor status: {mode_status}. Expected {get_enum_options(models.MonitorModeClass)}."
|
|
187
|
+
)
|
|
188
|
+
self._ensure_info().type = type
|
|
189
|
+
self._ensure_info().status = models.MonitorStatusClass(mode=mode_status)
|
|
190
|
+
elif isinstance(info, models.MonitorInfoClass):
|
|
191
|
+
self._set_aspect(info)
|
|
192
|
+
else:
|
|
193
|
+
assert_never(info)
|
|
194
|
+
|
|
195
|
+
@property
|
|
196
|
+
def external_url(self) -> Optional[str]:
|
|
197
|
+
"""Get the external URL of the monitor.
|
|
198
|
+
|
|
199
|
+
Returns:
|
|
200
|
+
The external URL if set, None otherwise.
|
|
201
|
+
"""
|
|
202
|
+
return self._ensure_info().externalUrl
|
|
203
|
+
|
|
204
|
+
def set_external_url(self, external_url: str) -> None:
|
|
205
|
+
"""Set the external URL of the monitor.
|
|
206
|
+
|
|
207
|
+
Args:
|
|
208
|
+
external_url: The external URL to set.
|
|
209
|
+
"""
|
|
210
|
+
self._ensure_info().externalUrl = external_url
|
|
211
|
+
|
|
212
|
+
@property
|
|
213
|
+
def custom_properties(self) -> Dict[str, str]:
|
|
214
|
+
"""Get the custom properties of the monitor.
|
|
215
|
+
|
|
216
|
+
Returns:
|
|
217
|
+
Dictionary of custom properties.
|
|
218
|
+
"""
|
|
219
|
+
return self._ensure_info().customProperties
|
|
220
|
+
|
|
221
|
+
def set_custom_properties(self, custom_properties: Dict[str, str]) -> None:
|
|
222
|
+
"""Set the custom properties of the monitor.
|
|
223
|
+
|
|
224
|
+
Args:
|
|
225
|
+
custom_properties: Dictionary of custom properties to set.
|
|
226
|
+
"""
|
|
227
|
+
self._ensure_info().customProperties = custom_properties
|
|
228
|
+
|
|
229
|
+
@property
|
|
230
|
+
def sensitivity(self) -> Optional[models.AssertionMonitorSensitivityClass]:
|
|
231
|
+
"""Get the sensitivity of the monitor.
|
|
232
|
+
|
|
233
|
+
Returns:
|
|
234
|
+
The sensitivity or None if not found.
|
|
235
|
+
"""
|
|
236
|
+
return _get_nested_field_for_entity_with_default(
|
|
237
|
+
self, "info.assertionMonitor.settings.adjustmentSettings.sensitivity"
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
@property
|
|
241
|
+
def exclusion_windows(self) -> Optional[list[models.AssertionExclusionWindowClass]]:
|
|
242
|
+
"""Get the exclusion windows of the monitor.
|
|
243
|
+
|
|
244
|
+
Returns:
|
|
245
|
+
The exclusion windows or None if not found.
|
|
246
|
+
"""
|
|
247
|
+
return _get_nested_field_for_entity_with_default(
|
|
248
|
+
self, "info.assertionMonitor.settings.adjustmentSettings.exclusionWindows"
|
|
249
|
+
)
|
|
250
|
+
|
|
251
|
+
@property
|
|
252
|
+
def training_data_lookback_days(self) -> Optional[int]:
|
|
253
|
+
"""Get the training data lookback days of the monitor.
|
|
254
|
+
|
|
255
|
+
Returns:
|
|
256
|
+
The training data lookback days or None if not found.
|
|
257
|
+
"""
|
|
258
|
+
return _get_nested_field_for_entity_with_default(
|
|
259
|
+
self,
|
|
260
|
+
"info.assertionMonitor.settings.adjustmentSettings.trainingDataLookbackWindowDays",
|
|
261
|
+
)
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
def _get_nested_field_for_entity_with_default(
|
|
265
|
+
entity: Entity,
|
|
266
|
+
field_path: str,
|
|
267
|
+
default: Any = None,
|
|
268
|
+
) -> Any:
|
|
269
|
+
"""
|
|
270
|
+
Get a nested field from an Entity object, and warn and return default if not found.
|
|
271
|
+
|
|
272
|
+
Args:
|
|
273
|
+
entity: The entity to get the nested field from.
|
|
274
|
+
field_path: The path to the nested field.
|
|
275
|
+
default: The default value to return if the field is not found.
|
|
276
|
+
"""
|
|
277
|
+
fields = field_path.split(".")
|
|
278
|
+
current = entity
|
|
279
|
+
last_valid_path = entity.entity_type_name()
|
|
280
|
+
|
|
281
|
+
for field in fields:
|
|
282
|
+
try:
|
|
283
|
+
current = getattr(current, field)
|
|
284
|
+
last_valid_path = f"{last_valid_path}.{field}"
|
|
285
|
+
except AttributeError:
|
|
286
|
+
logger.warning(
|
|
287
|
+
f"{entity.entity_type_name().capitalize()} {entity.urn} does not have an `{last_valid_path}` field, defaulting to {default}"
|
|
288
|
+
)
|
|
289
|
+
return default
|
|
290
|
+
|
|
291
|
+
return current
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
from typing import (
|
|
2
|
+
Type,
|
|
3
|
+
Union,
|
|
4
|
+
)
|
|
5
|
+
|
|
6
|
+
from typing_extensions import (
|
|
7
|
+
Self,
|
|
8
|
+
assert_never,
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
from datahub.emitter.mcp_builder import DatahubKey
|
|
12
|
+
from datahub.metadata import schema_classes as models
|
|
13
|
+
from datahub.metadata.urns import (
|
|
14
|
+
SubscriptionUrn,
|
|
15
|
+
Urn,
|
|
16
|
+
)
|
|
17
|
+
from datahub.sdk.entity import Entity
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class SubscriptionKey(DatahubKey):
|
|
21
|
+
"""
|
|
22
|
+
Key class for generating stable subscription identifiers.
|
|
23
|
+
|
|
24
|
+
The main goal is to have stable IDs that are deterministic based on the
|
|
25
|
+
entity and actor URNs, which helps prevent duplicate subscriptions during
|
|
26
|
+
eventual consistency scenarios when multiple subscription requests happen
|
|
27
|
+
in quick succession.
|
|
28
|
+
|
|
29
|
+
This implementation matches the behavior expected in the backend when a
|
|
30
|
+
subscription is created, ensuring consistent ID generation between the
|
|
31
|
+
Python SDK and Java backend services.
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
entity_urn: str
|
|
35
|
+
actor_urn: str
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class Subscription(Entity):
|
|
39
|
+
"""
|
|
40
|
+
Subscription entity class.
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
__slots__ = ()
|
|
44
|
+
|
|
45
|
+
@classmethod
|
|
46
|
+
def get_urn_type(cls) -> Type[SubscriptionUrn]:
|
|
47
|
+
"""Get the URN type for subscriptions.
|
|
48
|
+
|
|
49
|
+
Returns:
|
|
50
|
+
The SubscriptionUrn class.
|
|
51
|
+
"""
|
|
52
|
+
return SubscriptionUrn
|
|
53
|
+
|
|
54
|
+
def __init__(
|
|
55
|
+
self,
|
|
56
|
+
# SubscriptionInfo
|
|
57
|
+
info: models.SubscriptionInfoClass,
|
|
58
|
+
# Identity
|
|
59
|
+
id: Union[str, SubscriptionUrn],
|
|
60
|
+
):
|
|
61
|
+
"""
|
|
62
|
+
Initialize the Subscription entity.
|
|
63
|
+
"""
|
|
64
|
+
super().__init__(urn=Subscription._ensure_id(id))
|
|
65
|
+
|
|
66
|
+
self._set_info(info)
|
|
67
|
+
|
|
68
|
+
@classmethod
|
|
69
|
+
def _new_from_graph(cls, urn: Urn, current_aspects: models.AspectBag) -> Self:
|
|
70
|
+
assert isinstance(urn, SubscriptionUrn)
|
|
71
|
+
assert "subscriptionInfo" in current_aspects, "SubscriptionInfo is required"
|
|
72
|
+
subscription_info = current_aspects["subscriptionInfo"]
|
|
73
|
+
entity = cls(id=urn, info=subscription_info)
|
|
74
|
+
return entity._init_from_graph(current_aspects)
|
|
75
|
+
|
|
76
|
+
@property
|
|
77
|
+
def urn(self) -> SubscriptionUrn:
|
|
78
|
+
assert isinstance(self._urn, SubscriptionUrn)
|
|
79
|
+
return self._urn
|
|
80
|
+
|
|
81
|
+
@classmethod
|
|
82
|
+
def _ensure_id(cls, id: Union[str, SubscriptionUrn]) -> SubscriptionUrn:
|
|
83
|
+
if isinstance(id, str):
|
|
84
|
+
return SubscriptionUrn.from_string(id)
|
|
85
|
+
elif isinstance(id, SubscriptionUrn):
|
|
86
|
+
return id
|
|
87
|
+
else:
|
|
88
|
+
assert_never(id)
|
|
89
|
+
|
|
90
|
+
def _set_info(self, info: models.SubscriptionInfoClass) -> None:
|
|
91
|
+
self._set_aspect(info)
|
|
92
|
+
|
|
93
|
+
@property
|
|
94
|
+
def info(self) -> models.SubscriptionInfoClass:
|
|
95
|
+
"""
|
|
96
|
+
Get the SubscriptionInfo aspect of the subscription.
|
|
97
|
+
"""
|
|
98
|
+
subscription_info = self._get_aspect(models.SubscriptionInfoClass)
|
|
99
|
+
assert subscription_info is not None
|
|
100
|
+
return subscription_info
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from typing import Collection, Mapping, Union
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class SDKUsageError(Exception):
|
|
6
|
+
def __init__(self, msg: str):
|
|
7
|
+
super().__init__(msg)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class SDKUsageErrorWithExamples(SDKUsageError):
|
|
11
|
+
def __init__(
|
|
12
|
+
self,
|
|
13
|
+
msg: str,
|
|
14
|
+
examples: Union[
|
|
15
|
+
Mapping[str, Union[dict[str, str], str]], dict[str, Collection[str]]
|
|
16
|
+
],
|
|
17
|
+
):
|
|
18
|
+
super().__init__(msg)
|
|
19
|
+
self.msg = msg
|
|
20
|
+
self.examples = examples
|
|
21
|
+
|
|
22
|
+
def __str__(self) -> str:
|
|
23
|
+
examples_str = "\n\n".join(
|
|
24
|
+
f"Example - {key}:\n{json.dumps(value, indent=2) if isinstance(value, dict) else value}"
|
|
25
|
+
for key, value in self.examples.items()
|
|
26
|
+
)
|
|
27
|
+
return f"{self.msg}\n\n*** Examples of Accepted Values ***\n\n{examples_str}\n\n*** End of Examples ***"
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class SDKNotYetSupportedError(Exception):
|
|
31
|
+
def __init__(self, supported_item: str):
|
|
32
|
+
msg = f"This feature is not yet supported in the Python SDK: {supported_item}"
|
|
33
|
+
super().__init__(msg)
|
|
34
|
+
self.msg = msg
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
from typing import List, Optional
|
|
2
|
+
|
|
3
|
+
from datahub.metadata.urns import (
|
|
4
|
+
SubscriptionUrn,
|
|
5
|
+
)
|
|
6
|
+
from datahub.sdk.main_client import DataHubClient
|
|
7
|
+
from datahub.sdk.resolver_client import ResolverClient as OSSResolverClient
|
|
8
|
+
from datahub.sdk.search_filters import Filter, FilterDsl as F
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class ResolverClient(OSSResolverClient):
|
|
12
|
+
def __init__(self, client: DataHubClient):
|
|
13
|
+
super().__init__(client=client)
|
|
14
|
+
|
|
15
|
+
def subscription(
|
|
16
|
+
self,
|
|
17
|
+
*,
|
|
18
|
+
entity_urn: Optional[str] = None,
|
|
19
|
+
actor_urn: Optional[str] = None,
|
|
20
|
+
skip_cache: bool = False,
|
|
21
|
+
) -> List[SubscriptionUrn]:
|
|
22
|
+
"""Retrieve subscriptions for a given entity or actor, or both if both are given.
|
|
23
|
+
Args:
|
|
24
|
+
entity_urn: Optional URN of the entity to filter subscriptions by.
|
|
25
|
+
actor_urn: Optional URN of the actor to filter subscriptions by.
|
|
26
|
+
Returns:
|
|
27
|
+
List[SubscriptionUrn]: List of SubscriptionUrns matching the filters,
|
|
28
|
+
empty list if none.
|
|
29
|
+
"""
|
|
30
|
+
filters: List[Filter] = [F.entity_type(SubscriptionUrn.ENTITY_TYPE)]
|
|
31
|
+
|
|
32
|
+
if entity_urn is not None:
|
|
33
|
+
filters.append(F.custom_filter("entityUrn", "EQUAL", [entity_urn]))
|
|
34
|
+
|
|
35
|
+
if actor_urn is not None:
|
|
36
|
+
filters.append(F.custom_filter("actorUrn", "EQUAL", [actor_urn]))
|
|
37
|
+
|
|
38
|
+
filter = F.and_(*filters)
|
|
39
|
+
subscriptions = list(
|
|
40
|
+
self._client.search.get_urns(filter=filter, skip_cache=skip_cache)
|
|
41
|
+
)
|
|
42
|
+
return [SubscriptionUrn.from_string(urn) for urn in subscriptions]
|