acryl-datahub 1.1.1rc3__py3-none-any.whl → 1.2.0__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 might be problematic. Click here for more details.
- {acryl_datahub-1.1.1rc3.dist-info → acryl_datahub-1.2.0.dist-info}/METADATA +2559 -2532
- {acryl_datahub-1.1.1rc3.dist-info → acryl_datahub-1.2.0.dist-info}/RECORD +226 -190
- {acryl_datahub-1.1.1rc3.dist-info → acryl_datahub-1.2.0.dist-info}/WHEEL +1 -1
- {acryl_datahub-1.1.1rc3.dist-info → acryl_datahub-1.2.0.dist-info}/entry_points.txt +2 -0
- datahub/_version.py +1 -1
- datahub/api/entities/dataset/dataset.py +2 -1
- datahub/api/entities/external/__init__.py +0 -0
- datahub/api/entities/external/external_entities.py +239 -0
- datahub/api/entities/external/external_tag.py +145 -0
- datahub/api/entities/external/lake_formation_external_entites.py +161 -0
- datahub/api/entities/external/restricted_text.py +247 -0
- datahub/api/entities/external/unity_catalog_external_entites.py +173 -0
- datahub/cli/check_cli.py +88 -7
- datahub/cli/cli_utils.py +63 -0
- datahub/cli/container_cli.py +5 -0
- datahub/cli/delete_cli.py +124 -27
- datahub/cli/docker_check.py +107 -12
- datahub/cli/docker_cli.py +149 -227
- datahub/cli/exists_cli.py +0 -2
- datahub/cli/get_cli.py +0 -2
- datahub/cli/iceberg_cli.py +5 -0
- datahub/cli/ingest_cli.py +12 -16
- datahub/cli/migrate.py +2 -0
- datahub/cli/put_cli.py +1 -4
- datahub/cli/quickstart_versioning.py +50 -7
- datahub/cli/specific/assertions_cli.py +0 -4
- datahub/cli/specific/datacontract_cli.py +0 -3
- datahub/cli/specific/dataproduct_cli.py +0 -11
- datahub/cli/specific/dataset_cli.py +1 -8
- datahub/cli/specific/forms_cli.py +0 -4
- datahub/cli/specific/group_cli.py +0 -2
- datahub/cli/specific/structuredproperties_cli.py +1 -4
- datahub/cli/specific/user_cli.py +0 -2
- datahub/cli/state_cli.py +0 -2
- datahub/cli/timeline_cli.py +0 -2
- datahub/emitter/response_helper.py +86 -1
- datahub/emitter/rest_emitter.py +71 -13
- datahub/entrypoints.py +4 -3
- datahub/ingestion/api/decorators.py +15 -3
- datahub/ingestion/api/report.py +332 -3
- datahub/ingestion/api/sink.py +3 -0
- datahub/ingestion/api/source.py +48 -44
- datahub/ingestion/autogenerated/__init__.py +0 -0
- datahub/ingestion/autogenerated/capability_summary.json +3449 -0
- datahub/ingestion/autogenerated/lineage.json +401 -0
- datahub/ingestion/autogenerated/lineage_helper.py +177 -0
- datahub/ingestion/extractor/schema_util.py +13 -4
- datahub/ingestion/glossary/classification_mixin.py +5 -0
- datahub/ingestion/graph/client.py +100 -15
- datahub/ingestion/graph/config.py +1 -0
- datahub/ingestion/reporting/datahub_ingestion_run_summary_provider.py +20 -10
- datahub/ingestion/run/pipeline.py +54 -2
- datahub/ingestion/sink/datahub_rest.py +13 -0
- datahub/ingestion/source/abs/source.py +1 -1
- datahub/ingestion/source/aws/aws_common.py +4 -0
- datahub/ingestion/source/aws/glue.py +489 -244
- datahub/ingestion/source/aws/tag_entities.py +292 -0
- datahub/ingestion/source/azure/azure_common.py +2 -2
- datahub/ingestion/source/bigquery_v2/bigquery.py +50 -23
- datahub/ingestion/source/bigquery_v2/bigquery_config.py +1 -1
- datahub/ingestion/source/bigquery_v2/bigquery_queries.py +1 -0
- datahub/ingestion/source/bigquery_v2/bigquery_schema_gen.py +2 -0
- datahub/ingestion/source/bigquery_v2/common.py +1 -1
- datahub/ingestion/source/bigquery_v2/profiler.py +4 -2
- datahub/ingestion/source/bigquery_v2/queries.py +3 -3
- datahub/ingestion/source/cassandra/cassandra.py +1 -1
- datahub/ingestion/source/cassandra/cassandra_profiling.py +6 -5
- datahub/ingestion/source/common/subtypes.py +45 -0
- datahub/ingestion/source/data_lake_common/object_store.py +115 -27
- datahub/ingestion/source/data_lake_common/path_spec.py +10 -21
- datahub/ingestion/source/datahub/config.py +11 -0
- datahub/ingestion/source/datahub/datahub_database_reader.py +187 -35
- datahub/ingestion/source/datahub/datahub_source.py +1 -1
- datahub/ingestion/source/dbt/dbt_cloud.py +10 -2
- datahub/ingestion/source/dbt/dbt_common.py +6 -2
- datahub/ingestion/source/dbt/dbt_core.py +3 -0
- datahub/ingestion/source/debug/__init__.py +0 -0
- datahub/ingestion/source/debug/datahub_debug.py +300 -0
- datahub/ingestion/source/dremio/dremio_api.py +114 -73
- datahub/ingestion/source/dremio/dremio_config.py +2 -0
- datahub/ingestion/source/dremio/dremio_reporting.py +23 -2
- datahub/ingestion/source/dremio/dremio_source.py +94 -81
- datahub/ingestion/source/dremio/dremio_sql_queries.py +82 -21
- datahub/ingestion/source/file.py +3 -0
- datahub/ingestion/source/fivetran/fivetran.py +34 -26
- datahub/ingestion/source/gcs/gcs_source.py +13 -2
- datahub/ingestion/source/ge_data_profiler.py +76 -28
- datahub/ingestion/source/ge_profiling_config.py +11 -0
- datahub/ingestion/source/hex/api.py +26 -1
- datahub/ingestion/source/iceberg/iceberg.py +3 -1
- datahub/ingestion/source/identity/azure_ad.py +1 -1
- datahub/ingestion/source/identity/okta.py +1 -14
- datahub/ingestion/source/kafka/kafka.py +16 -0
- datahub/ingestion/source/kafka_connect/sink_connectors.py +156 -47
- datahub/ingestion/source/kafka_connect/source_connectors.py +59 -4
- datahub/ingestion/source/looker/looker_source.py +1 -0
- datahub/ingestion/source/mlflow.py +11 -1
- datahub/ingestion/source/mock_data/__init__.py +0 -0
- datahub/ingestion/source/mock_data/datahub_mock_data.py +472 -0
- datahub/ingestion/source/mock_data/datahub_mock_data_report.py +12 -0
- datahub/ingestion/source/mock_data/table_naming_helper.py +91 -0
- datahub/ingestion/source/nifi.py +1 -1
- datahub/ingestion/source/openapi.py +12 -0
- datahub/ingestion/source/openapi_parser.py +56 -37
- datahub/ingestion/source/powerbi/powerbi.py +1 -5
- datahub/ingestion/source/powerbi/rest_api_wrapper/powerbi_api.py +0 -1
- datahub/ingestion/source/powerbi_report_server/report_server.py +0 -23
- datahub/ingestion/source/preset.py +2 -2
- datahub/ingestion/source/qlik_sense/qlik_sense.py +1 -0
- datahub/ingestion/source/redshift/redshift.py +21 -1
- datahub/ingestion/source/redshift/usage.py +4 -3
- datahub/ingestion/source/s3/report.py +4 -2
- datahub/ingestion/source/s3/source.py +367 -115
- datahub/ingestion/source/sac/sac.py +3 -1
- datahub/ingestion/source/salesforce.py +6 -3
- datahub/ingestion/source/sigma/sigma.py +7 -1
- datahub/ingestion/source/slack/slack.py +2 -1
- datahub/ingestion/source/snowflake/snowflake_config.py +43 -7
- datahub/ingestion/source/snowflake/snowflake_queries.py +348 -82
- datahub/ingestion/source/snowflake/snowflake_summary.py +5 -0
- datahub/ingestion/source/snowflake/snowflake_usage_v2.py +8 -2
- datahub/ingestion/source/snowflake/snowflake_utils.py +2 -7
- datahub/ingestion/source/snowflake/snowflake_v2.py +33 -8
- datahub/ingestion/source/snowflake/stored_proc_lineage.py +143 -0
- datahub/ingestion/source/sql/athena.py +119 -11
- datahub/ingestion/source/sql/athena_properties_extractor.py +777 -0
- datahub/ingestion/source/sql/clickhouse.py +3 -1
- datahub/ingestion/source/sql/cockroachdb.py +0 -1
- datahub/ingestion/source/sql/hana.py +3 -1
- datahub/ingestion/source/sql/hive_metastore.py +3 -11
- datahub/ingestion/source/sql/mariadb.py +0 -1
- datahub/ingestion/source/sql/mssql/source.py +239 -34
- datahub/ingestion/source/sql/mysql.py +0 -1
- datahub/ingestion/source/sql/oracle.py +1 -1
- datahub/ingestion/source/sql/postgres.py +0 -1
- datahub/ingestion/source/sql/sql_common.py +121 -34
- datahub/ingestion/source/sql/sql_generic_profiler.py +2 -1
- datahub/ingestion/source/sql/teradata.py +997 -235
- datahub/ingestion/source/sql/vertica.py +10 -6
- datahub/ingestion/source/sql_queries.py +2 -2
- datahub/ingestion/source/state/stateful_ingestion_base.py +1 -1
- datahub/ingestion/source/superset.py +58 -3
- datahub/ingestion/source/tableau/tableau.py +58 -37
- datahub/ingestion/source/tableau/tableau_common.py +4 -2
- datahub/ingestion/source/tableau/tableau_constant.py +0 -4
- datahub/ingestion/source/unity/config.py +5 -0
- datahub/ingestion/source/unity/proxy.py +118 -0
- datahub/ingestion/source/unity/source.py +195 -17
- datahub/ingestion/source/unity/tag_entities.py +295 -0
- datahub/ingestion/source/usage/clickhouse_usage.py +4 -1
- datahub/ingestion/source/usage/starburst_trino_usage.py +3 -0
- datahub/ingestion/transformer/add_dataset_ownership.py +18 -2
- datahub/integrations/assertion/snowflake/compiler.py +4 -3
- datahub/metadata/_internal_schema_classes.py +1446 -559
- datahub/metadata/_urns/urn_defs.py +1721 -1553
- datahub/metadata/com/linkedin/pegasus2avro/application/__init__.py +19 -0
- datahub/metadata/com/linkedin/pegasus2avro/identity/__init__.py +2 -0
- datahub/metadata/com/linkedin/pegasus2avro/logical/__init__.py +15 -0
- datahub/metadata/com/linkedin/pegasus2avro/metadata/key/__init__.py +4 -0
- datahub/metadata/com/linkedin/pegasus2avro/module/__init__.py +27 -0
- datahub/metadata/com/linkedin/pegasus2avro/settings/global/__init__.py +4 -0
- datahub/metadata/com/linkedin/pegasus2avro/template/__init__.py +25 -0
- datahub/metadata/schema.avsc +18055 -17802
- datahub/metadata/schemas/ApplicationKey.avsc +31 -0
- datahub/metadata/schemas/ApplicationProperties.avsc +72 -0
- datahub/metadata/schemas/Applications.avsc +38 -0
- datahub/metadata/schemas/ChartKey.avsc +1 -0
- datahub/metadata/schemas/ContainerKey.avsc +1 -0
- datahub/metadata/schemas/ContainerProperties.avsc +8 -0
- datahub/metadata/schemas/CorpUserSettings.avsc +41 -0
- datahub/metadata/schemas/DashboardKey.avsc +1 -0
- datahub/metadata/schemas/DataFlowInfo.avsc +8 -0
- datahub/metadata/schemas/DataFlowKey.avsc +1 -0
- datahub/metadata/schemas/DataHubPageModuleKey.avsc +21 -0
- datahub/metadata/schemas/DataHubPageModuleProperties.avsc +200 -0
- datahub/metadata/schemas/DataHubPageTemplateKey.avsc +21 -0
- datahub/metadata/schemas/DataHubPageTemplateProperties.avsc +175 -0
- datahub/metadata/schemas/DataHubPolicyInfo.avsc +12 -1
- datahub/metadata/schemas/DataJobInfo.avsc +8 -0
- datahub/metadata/schemas/DataJobKey.avsc +1 -0
- datahub/metadata/schemas/DataProcessKey.avsc +8 -0
- datahub/metadata/schemas/DataProductKey.avsc +1 -0
- datahub/metadata/schemas/DataProductProperties.avsc +1 -1
- datahub/metadata/schemas/DatasetKey.avsc +11 -1
- datahub/metadata/schemas/ExecutionRequestInput.avsc +5 -0
- datahub/metadata/schemas/GlobalSettingsInfo.avsc +62 -0
- datahub/metadata/schemas/GlossaryTermKey.avsc +1 -0
- datahub/metadata/schemas/IcebergWarehouseInfo.avsc +8 -0
- datahub/metadata/schemas/LogicalParent.avsc +140 -0
- datahub/metadata/schemas/MLFeatureKey.avsc +1 -0
- datahub/metadata/schemas/MLFeatureTableKey.avsc +1 -0
- datahub/metadata/schemas/MLModelDeploymentKey.avsc +8 -0
- datahub/metadata/schemas/MLModelGroupKey.avsc +9 -0
- datahub/metadata/schemas/MLModelKey.avsc +9 -0
- datahub/metadata/schemas/MLPrimaryKeyKey.avsc +1 -0
- datahub/metadata/schemas/MetadataChangeEvent.avsc +20 -1
- datahub/metadata/schemas/NotebookKey.avsc +1 -0
- datahub/metadata/schemas/QuerySubjects.avsc +1 -12
- datahub/metadata/schemas/SchemaFieldKey.avsc +2 -1
- datahub/sdk/__init__.py +6 -0
- datahub/sdk/_all_entities.py +11 -0
- datahub/sdk/_shared.py +118 -1
- datahub/sdk/chart.py +315 -0
- datahub/sdk/container.py +7 -0
- datahub/sdk/dashboard.py +432 -0
- datahub/sdk/dataflow.py +309 -0
- datahub/sdk/datajob.py +367 -0
- datahub/sdk/dataset.py +8 -2
- datahub/sdk/entity_client.py +90 -2
- datahub/sdk/lineage_client.py +683 -82
- datahub/sdk/main_client.py +46 -16
- datahub/sdk/mlmodel.py +101 -38
- datahub/sdk/mlmodelgroup.py +7 -0
- datahub/sdk/search_client.py +4 -3
- datahub/specific/chart.py +1 -1
- datahub/specific/dataproduct.py +4 -0
- datahub/sql_parsing/sql_parsing_aggregator.py +29 -17
- datahub/sql_parsing/sqlglot_lineage.py +62 -13
- datahub/telemetry/telemetry.py +17 -11
- datahub/testing/sdk_v2_helpers.py +7 -1
- datahub/upgrade/upgrade.py +46 -13
- datahub/utilities/server_config_util.py +8 -0
- datahub/utilities/sqlalchemy_query_combiner.py +5 -2
- datahub/utilities/stats_collections.py +4 -0
- {acryl_datahub-1.1.1rc3.dist-info → acryl_datahub-1.2.0.dist-info}/licenses/LICENSE +0 -0
- {acryl_datahub-1.1.1rc3.dist-info → acryl_datahub-1.2.0.dist-info}/top_level.txt +0 -0
datahub/sdk/dashboard.py
ADDED
|
@@ -0,0 +1,432 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from datetime import datetime
|
|
4
|
+
from typing import Dict, List, Optional, Type, Union
|
|
5
|
+
|
|
6
|
+
from typing_extensions import Self
|
|
7
|
+
|
|
8
|
+
import datahub.metadata.schema_classes as models
|
|
9
|
+
from datahub.metadata.urns import ChartUrn, DashboardUrn, DatasetUrn, Urn
|
|
10
|
+
from datahub.sdk._shared import (
|
|
11
|
+
ChartUrnOrStr,
|
|
12
|
+
DashboardUrnOrStr,
|
|
13
|
+
DataPlatformInstanceUrnOrStr,
|
|
14
|
+
DataPlatformUrnOrStr,
|
|
15
|
+
DatasetUrnOrStr,
|
|
16
|
+
DomainInputType,
|
|
17
|
+
HasContainer,
|
|
18
|
+
HasDomain,
|
|
19
|
+
HasInstitutionalMemory,
|
|
20
|
+
HasOwnership,
|
|
21
|
+
HasPlatformInstance,
|
|
22
|
+
HasSubtype,
|
|
23
|
+
HasTags,
|
|
24
|
+
HasTerms,
|
|
25
|
+
LinksInputType,
|
|
26
|
+
OwnersInputType,
|
|
27
|
+
TagsInputType,
|
|
28
|
+
TermsInputType,
|
|
29
|
+
)
|
|
30
|
+
from datahub.sdk.chart import Chart
|
|
31
|
+
from datahub.sdk.dataset import Dataset
|
|
32
|
+
from datahub.sdk.entity import Entity, ExtraAspectsType
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class Dashboard(
|
|
36
|
+
HasPlatformInstance,
|
|
37
|
+
HasSubtype,
|
|
38
|
+
HasOwnership,
|
|
39
|
+
HasContainer,
|
|
40
|
+
HasInstitutionalMemory,
|
|
41
|
+
HasTags,
|
|
42
|
+
HasTerms,
|
|
43
|
+
HasDomain,
|
|
44
|
+
Entity,
|
|
45
|
+
):
|
|
46
|
+
"""Represents a dashboard in DataHub."""
|
|
47
|
+
|
|
48
|
+
__slots__ = ()
|
|
49
|
+
|
|
50
|
+
@classmethod
|
|
51
|
+
def get_urn_type(cls) -> Type[DashboardUrn]:
|
|
52
|
+
"""Get the URN type for dashboards.
|
|
53
|
+
Returns:
|
|
54
|
+
The DashboardUrn class.
|
|
55
|
+
"""
|
|
56
|
+
return DashboardUrn
|
|
57
|
+
|
|
58
|
+
def __init__(
|
|
59
|
+
self,
|
|
60
|
+
*,
|
|
61
|
+
# Identity.
|
|
62
|
+
name: str,
|
|
63
|
+
platform: DataPlatformUrnOrStr,
|
|
64
|
+
display_name: Optional[str] = None,
|
|
65
|
+
platform_instance: Optional[DataPlatformInstanceUrnOrStr] = None,
|
|
66
|
+
# Dashboard properties.
|
|
67
|
+
description: str = "",
|
|
68
|
+
external_url: Optional[str] = None,
|
|
69
|
+
dashboard_url: Optional[str] = None,
|
|
70
|
+
custom_properties: Optional[Dict[str, str]] = None,
|
|
71
|
+
last_modified: Optional[datetime] = None,
|
|
72
|
+
last_refreshed: Optional[datetime] = None,
|
|
73
|
+
input_datasets: Optional[List[Union[DatasetUrnOrStr, Dataset]]] = None,
|
|
74
|
+
charts: Optional[List[Union[ChartUrnOrStr, Chart]]] = None,
|
|
75
|
+
dashboards: Optional[List[Union[DashboardUrnOrStr, Dashboard]]] = None,
|
|
76
|
+
# Standard aspects.
|
|
77
|
+
subtype: Optional[str] = None,
|
|
78
|
+
owners: Optional[OwnersInputType] = None,
|
|
79
|
+
links: Optional[LinksInputType] = None,
|
|
80
|
+
tags: Optional[TagsInputType] = None,
|
|
81
|
+
terms: Optional[TermsInputType] = None,
|
|
82
|
+
domain: Optional[DomainInputType] = None,
|
|
83
|
+
extra_aspects: ExtraAspectsType = None,
|
|
84
|
+
):
|
|
85
|
+
"""Initialize a new Dashboard instance."""
|
|
86
|
+
urn = DashboardUrn.create_from_ids(
|
|
87
|
+
platform=str(platform),
|
|
88
|
+
name=name,
|
|
89
|
+
platform_instance=str(platform_instance) if platform_instance else None,
|
|
90
|
+
)
|
|
91
|
+
super().__init__(urn)
|
|
92
|
+
self._set_extra_aspects(extra_aspects)
|
|
93
|
+
|
|
94
|
+
self._set_platform_instance(platform, platform_instance)
|
|
95
|
+
|
|
96
|
+
# Initialize DashboardInfoClass with default values
|
|
97
|
+
dashboard_info = models.DashboardInfoClass(
|
|
98
|
+
title=display_name or name,
|
|
99
|
+
description=description or "",
|
|
100
|
+
lastModified=models.ChangeAuditStampsClass(
|
|
101
|
+
lastModified=None,
|
|
102
|
+
),
|
|
103
|
+
customProperties={},
|
|
104
|
+
chartEdges=[],
|
|
105
|
+
datasetEdges=[],
|
|
106
|
+
dashboards=[],
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
if last_modified:
|
|
110
|
+
dashboard_info.lastModified = models.ChangeAuditStampsClass(
|
|
111
|
+
lastModified=models.AuditStampClass(
|
|
112
|
+
time=int(last_modified.timestamp()),
|
|
113
|
+
actor="urn:li:corpuser:datahub",
|
|
114
|
+
),
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
# Set additional properties
|
|
118
|
+
if description is not None:
|
|
119
|
+
self.set_description(description)
|
|
120
|
+
if display_name is not None:
|
|
121
|
+
self.set_display_name(display_name)
|
|
122
|
+
if external_url is not None:
|
|
123
|
+
self.set_external_url(external_url)
|
|
124
|
+
if dashboard_url is not None:
|
|
125
|
+
self.set_dashboard_url(dashboard_url)
|
|
126
|
+
if custom_properties is not None:
|
|
127
|
+
self.set_custom_properties(custom_properties)
|
|
128
|
+
if last_modified is not None:
|
|
129
|
+
self.set_last_modified(last_modified)
|
|
130
|
+
if last_refreshed is not None:
|
|
131
|
+
self.set_last_refreshed(last_refreshed)
|
|
132
|
+
if subtype is not None:
|
|
133
|
+
self.set_subtype(subtype)
|
|
134
|
+
if owners is not None:
|
|
135
|
+
self.set_owners(owners)
|
|
136
|
+
if links is not None:
|
|
137
|
+
self.set_links(links)
|
|
138
|
+
if tags is not None:
|
|
139
|
+
self.set_tags(tags)
|
|
140
|
+
if terms is not None:
|
|
141
|
+
self.set_terms(terms)
|
|
142
|
+
if domain is not None:
|
|
143
|
+
self.set_domain(domain)
|
|
144
|
+
if input_datasets is not None:
|
|
145
|
+
self.set_input_datasets(input_datasets)
|
|
146
|
+
if charts is not None:
|
|
147
|
+
self.set_charts(charts)
|
|
148
|
+
if dashboards is not None:
|
|
149
|
+
self.set_dashboards(dashboards)
|
|
150
|
+
|
|
151
|
+
@classmethod
|
|
152
|
+
def _new_from_graph(cls, urn: Urn, current_aspects: models.AspectBag) -> Self:
|
|
153
|
+
assert isinstance(urn, DashboardUrn)
|
|
154
|
+
entity = cls(
|
|
155
|
+
platform=urn.dashboard_tool,
|
|
156
|
+
name=urn.dashboard_id,
|
|
157
|
+
)
|
|
158
|
+
return entity._init_from_graph(current_aspects)
|
|
159
|
+
|
|
160
|
+
@property
|
|
161
|
+
def urn(self) -> DashboardUrn:
|
|
162
|
+
assert isinstance(self._urn, DashboardUrn)
|
|
163
|
+
return self._urn
|
|
164
|
+
|
|
165
|
+
def _ensure_dashboard_props(self) -> models.DashboardInfoClass:
|
|
166
|
+
"""Get the dashboard properties safely."""
|
|
167
|
+
return self._setdefault_aspect(
|
|
168
|
+
models.DashboardInfoClass(
|
|
169
|
+
title=self.urn.dashboard_id,
|
|
170
|
+
description="",
|
|
171
|
+
lastModified=models.ChangeAuditStampsClass(
|
|
172
|
+
lastModified=models.AuditStampClass(
|
|
173
|
+
time=0, actor="urn:li:corpuser:unknown"
|
|
174
|
+
)
|
|
175
|
+
),
|
|
176
|
+
customProperties={},
|
|
177
|
+
chartEdges=[],
|
|
178
|
+
datasetEdges=[],
|
|
179
|
+
dashboards=[],
|
|
180
|
+
)
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
@property
|
|
184
|
+
def name(self) -> str:
|
|
185
|
+
"""Get the name of the dashboard."""
|
|
186
|
+
return self.urn.dashboard_id
|
|
187
|
+
|
|
188
|
+
@property
|
|
189
|
+
def title(self) -> str:
|
|
190
|
+
"""Get the title of the dashboard."""
|
|
191
|
+
return self._ensure_dashboard_props().title
|
|
192
|
+
|
|
193
|
+
def set_title(self, title: str) -> None:
|
|
194
|
+
"""Set the title of the dashboard."""
|
|
195
|
+
props = self._ensure_dashboard_props()
|
|
196
|
+
props.title = title
|
|
197
|
+
self._set_aspect(props)
|
|
198
|
+
|
|
199
|
+
@property
|
|
200
|
+
def description(self) -> Optional[str]:
|
|
201
|
+
"""Get the description of the dashboard."""
|
|
202
|
+
props = self._ensure_dashboard_props()
|
|
203
|
+
return props.description
|
|
204
|
+
|
|
205
|
+
def set_description(self, description: str) -> None:
|
|
206
|
+
"""Set the description of the dashboard."""
|
|
207
|
+
props = self._ensure_dashboard_props()
|
|
208
|
+
props.description = description
|
|
209
|
+
self._set_aspect(props)
|
|
210
|
+
|
|
211
|
+
@property
|
|
212
|
+
def display_name(self) -> Optional[str]:
|
|
213
|
+
"""Get the display name of the dashboard."""
|
|
214
|
+
return self.title
|
|
215
|
+
|
|
216
|
+
def set_display_name(self, display_name: str) -> None:
|
|
217
|
+
"""Set the display name of the dashboard."""
|
|
218
|
+
self.set_title(display_name)
|
|
219
|
+
|
|
220
|
+
@property
|
|
221
|
+
def external_url(self) -> Optional[str]:
|
|
222
|
+
"""Get the external URL of the dashboard."""
|
|
223
|
+
props = self._ensure_dashboard_props()
|
|
224
|
+
return props.externalUrl
|
|
225
|
+
|
|
226
|
+
def set_external_url(self, external_url: str) -> None:
|
|
227
|
+
"""Set the external URL of the dashboard."""
|
|
228
|
+
props = self._ensure_dashboard_props()
|
|
229
|
+
props.externalUrl = external_url
|
|
230
|
+
self._set_aspect(props)
|
|
231
|
+
|
|
232
|
+
@property
|
|
233
|
+
def dashboard_url(self) -> Optional[str]:
|
|
234
|
+
"""Get the dashboard URL."""
|
|
235
|
+
props = self._ensure_dashboard_props()
|
|
236
|
+
return props.dashboardUrl
|
|
237
|
+
|
|
238
|
+
def set_dashboard_url(self, dashboard_url: str) -> None:
|
|
239
|
+
"""Set the dashboard URL."""
|
|
240
|
+
props = self._ensure_dashboard_props()
|
|
241
|
+
props.dashboardUrl = dashboard_url
|
|
242
|
+
self._set_aspect(props)
|
|
243
|
+
|
|
244
|
+
@property
|
|
245
|
+
def custom_properties(self) -> Dict[str, str]:
|
|
246
|
+
"""Get the custom properties of the dashboard."""
|
|
247
|
+
props = self._ensure_dashboard_props()
|
|
248
|
+
return props.customProperties or {}
|
|
249
|
+
|
|
250
|
+
def set_custom_properties(self, custom_properties: Dict[str, str]) -> None:
|
|
251
|
+
"""Set the custom properties of the dashboard."""
|
|
252
|
+
props = self._ensure_dashboard_props()
|
|
253
|
+
props.customProperties = custom_properties
|
|
254
|
+
self._set_aspect(props)
|
|
255
|
+
|
|
256
|
+
@property
|
|
257
|
+
def last_modified(self) -> Optional[datetime]:
|
|
258
|
+
"""Get the last modification timestamp of the dashboard."""
|
|
259
|
+
props = self._ensure_dashboard_props()
|
|
260
|
+
if props.lastModified.lastModified.time == 0:
|
|
261
|
+
return None
|
|
262
|
+
return datetime.fromtimestamp(props.lastModified.lastModified.time)
|
|
263
|
+
|
|
264
|
+
def set_last_modified(self, last_modified: datetime) -> None:
|
|
265
|
+
"""Set the last modification timestamp of the dashboard."""
|
|
266
|
+
props = self._ensure_dashboard_props()
|
|
267
|
+
props.lastModified = models.ChangeAuditStampsClass(
|
|
268
|
+
lastModified=models.AuditStampClass(
|
|
269
|
+
time=int(last_modified.timestamp()),
|
|
270
|
+
actor="urn:li:corpuser:datahub",
|
|
271
|
+
),
|
|
272
|
+
)
|
|
273
|
+
self._set_aspect(props)
|
|
274
|
+
|
|
275
|
+
@property
|
|
276
|
+
def last_refreshed(self) -> Optional[datetime]:
|
|
277
|
+
"""Get the last refresh timestamp of the dashboard."""
|
|
278
|
+
props = self._ensure_dashboard_props()
|
|
279
|
+
return (
|
|
280
|
+
datetime.fromtimestamp(props.lastRefreshed)
|
|
281
|
+
if props.lastRefreshed is not None
|
|
282
|
+
else None
|
|
283
|
+
)
|
|
284
|
+
|
|
285
|
+
def set_last_refreshed(self, last_refreshed: datetime) -> None:
|
|
286
|
+
"""Set the last refresh timestamp of the dashboard."""
|
|
287
|
+
props = self._ensure_dashboard_props()
|
|
288
|
+
props.lastRefreshed = int(last_refreshed.timestamp())
|
|
289
|
+
self._set_aspect(props)
|
|
290
|
+
|
|
291
|
+
@property
|
|
292
|
+
def input_datasets(self) -> List[DatasetUrn]:
|
|
293
|
+
"""Get the input datasets of the dashboard."""
|
|
294
|
+
props = self._ensure_dashboard_props()
|
|
295
|
+
return [
|
|
296
|
+
DatasetUrn.from_string(edge.destinationUrn)
|
|
297
|
+
for edge in (props.datasetEdges or [])
|
|
298
|
+
]
|
|
299
|
+
|
|
300
|
+
def set_input_datasets(
|
|
301
|
+
self, input_datasets: List[Union[DatasetUrnOrStr, Dataset]]
|
|
302
|
+
) -> None:
|
|
303
|
+
"""Set the input datasets of the dashboard."""
|
|
304
|
+
props = self._ensure_dashboard_props()
|
|
305
|
+
dataset_edges = props.datasetEdges or []
|
|
306
|
+
for dataset in input_datasets:
|
|
307
|
+
if isinstance(dataset, Dataset):
|
|
308
|
+
dataset_urn = dataset.urn
|
|
309
|
+
else:
|
|
310
|
+
dataset_urn = DatasetUrn.from_string(dataset)
|
|
311
|
+
dataset_edges.append(models.EdgeClass(destinationUrn=str(dataset_urn)))
|
|
312
|
+
props.datasetEdges = dataset_edges
|
|
313
|
+
self._set_aspect(props)
|
|
314
|
+
|
|
315
|
+
def add_input_dataset(self, input_dataset: Union[DatasetUrnOrStr, Dataset]) -> None:
|
|
316
|
+
"""Add an input dataset to the dashboard."""
|
|
317
|
+
if isinstance(input_dataset, Dataset):
|
|
318
|
+
input_dataset_urn = input_dataset.urn
|
|
319
|
+
else:
|
|
320
|
+
input_dataset_urn = DatasetUrn.from_string(input_dataset)
|
|
321
|
+
props = self._ensure_dashboard_props()
|
|
322
|
+
dataset_edges = props.datasetEdges or []
|
|
323
|
+
existing_urns = [edge.destinationUrn for edge in dataset_edges]
|
|
324
|
+
if str(input_dataset_urn) not in existing_urns:
|
|
325
|
+
dataset_edges.append(
|
|
326
|
+
models.EdgeClass(destinationUrn=str(input_dataset_urn))
|
|
327
|
+
)
|
|
328
|
+
props.datasetEdges = dataset_edges
|
|
329
|
+
self._set_aspect(props)
|
|
330
|
+
|
|
331
|
+
def remove_input_dataset(
|
|
332
|
+
self, input_dataset: Union[DatasetUrnOrStr, Dataset]
|
|
333
|
+
) -> None:
|
|
334
|
+
"""Remove an input dataset from the dashboard."""
|
|
335
|
+
if isinstance(input_dataset, Dataset):
|
|
336
|
+
input_dataset_urn = input_dataset.urn
|
|
337
|
+
else:
|
|
338
|
+
input_dataset_urn = DatasetUrn.from_string(input_dataset)
|
|
339
|
+
props = self._ensure_dashboard_props()
|
|
340
|
+
props.datasetEdges = [
|
|
341
|
+
edge
|
|
342
|
+
for edge in (props.datasetEdges or [])
|
|
343
|
+
if edge.destinationUrn != str(input_dataset_urn)
|
|
344
|
+
]
|
|
345
|
+
self._set_aspect(props)
|
|
346
|
+
|
|
347
|
+
@property
|
|
348
|
+
def charts(self) -> List[ChartUrn]:
|
|
349
|
+
"""Get the charts of the dashboard."""
|
|
350
|
+
chart_edges = self._ensure_dashboard_props().chartEdges
|
|
351
|
+
if chart_edges is None:
|
|
352
|
+
return []
|
|
353
|
+
return [ChartUrn.from_string(edge.destinationUrn) for edge in chart_edges]
|
|
354
|
+
|
|
355
|
+
def set_charts(self, charts: List[Union[ChartUrnOrStr, Chart]]) -> None:
|
|
356
|
+
"""Set the charts of the dashboard."""
|
|
357
|
+
props = self._ensure_dashboard_props()
|
|
358
|
+
chart_edges = props.chartEdges or []
|
|
359
|
+
for chart in charts:
|
|
360
|
+
if isinstance(chart, Chart):
|
|
361
|
+
chart_urn = chart.urn
|
|
362
|
+
else:
|
|
363
|
+
chart_urn = ChartUrn.from_string(chart)
|
|
364
|
+
chart_edges.append(models.EdgeClass(destinationUrn=str(chart_urn)))
|
|
365
|
+
props.chartEdges = chart_edges
|
|
366
|
+
self._set_aspect(props)
|
|
367
|
+
|
|
368
|
+
def add_chart(self, chart: Union[ChartUrnOrStr, Chart]) -> None:
|
|
369
|
+
"""Add a chart to the dashboard."""
|
|
370
|
+
if isinstance(chart, Chart):
|
|
371
|
+
chart_urn = chart.urn
|
|
372
|
+
else:
|
|
373
|
+
chart_urn = ChartUrn.from_string(chart)
|
|
374
|
+
props = self._ensure_dashboard_props()
|
|
375
|
+
chart_edges = props.chartEdges or []
|
|
376
|
+
existing_urns = [
|
|
377
|
+
edge.destinationUrn
|
|
378
|
+
for edge in chart_edges
|
|
379
|
+
if edge.destinationUrn is not None
|
|
380
|
+
]
|
|
381
|
+
if str(chart_urn) not in existing_urns:
|
|
382
|
+
chart_edges.append(models.EdgeClass(destinationUrn=str(chart_urn)))
|
|
383
|
+
props.chartEdges = chart_edges
|
|
384
|
+
self._set_aspect(props)
|
|
385
|
+
|
|
386
|
+
def remove_chart(self, chart: Union[ChartUrnOrStr, Chart]) -> None:
|
|
387
|
+
"""Remove a chart from the dashboard."""
|
|
388
|
+
if isinstance(chart, Chart):
|
|
389
|
+
chart_urn = chart.urn
|
|
390
|
+
else:
|
|
391
|
+
chart_urn = ChartUrn.from_string(chart)
|
|
392
|
+
props = self._ensure_dashboard_props()
|
|
393
|
+
props.chartEdges = [
|
|
394
|
+
edge
|
|
395
|
+
for edge in (props.chartEdges or [])
|
|
396
|
+
if edge.destinationUrn != str(chart_urn)
|
|
397
|
+
]
|
|
398
|
+
self._set_aspect(props)
|
|
399
|
+
|
|
400
|
+
@property
|
|
401
|
+
def dashboards(self) -> List[DashboardUrn]:
|
|
402
|
+
"""Get the dashboards of the dashboard."""
|
|
403
|
+
props = self._ensure_dashboard_props()
|
|
404
|
+
return [
|
|
405
|
+
DashboardUrn.from_string(dashboard.destinationUrn)
|
|
406
|
+
for dashboard in (props.dashboards or [])
|
|
407
|
+
]
|
|
408
|
+
|
|
409
|
+
def set_dashboards(
|
|
410
|
+
self, dashboards: List[Union[DashboardUrnOrStr, Dashboard]]
|
|
411
|
+
) -> None:
|
|
412
|
+
"""Set the dashboards of the dashboard."""
|
|
413
|
+
props = self._ensure_dashboard_props()
|
|
414
|
+
for dashboard in dashboards:
|
|
415
|
+
if isinstance(dashboard, Dashboard):
|
|
416
|
+
dashboard_urn = dashboard.urn
|
|
417
|
+
else:
|
|
418
|
+
dashboard_urn = DashboardUrn.from_string(dashboard)
|
|
419
|
+
props.dashboards.append(models.EdgeClass(destinationUrn=str(dashboard_urn)))
|
|
420
|
+
self._set_aspect(props)
|
|
421
|
+
|
|
422
|
+
def add_dashboard(self, dashboard: Union[DashboardUrnOrStr, Dashboard]) -> None:
|
|
423
|
+
"""Add a dashboard to the dashboard."""
|
|
424
|
+
if isinstance(dashboard, Dashboard):
|
|
425
|
+
dashboard_urn = dashboard.urn
|
|
426
|
+
else:
|
|
427
|
+
dashboard_urn = DashboardUrn.from_string(dashboard)
|
|
428
|
+
props = self._ensure_dashboard_props()
|
|
429
|
+
dashboards = props.dashboards or []
|
|
430
|
+
existing_urns = [dashboard.destinationUrn for dashboard in dashboards]
|
|
431
|
+
if str(dashboard_urn) not in existing_urns:
|
|
432
|
+
dashboards.append(models.EdgeClass(destinationUrn=str(dashboard_urn)))
|