Skip to content

Commit ba6e383

Browse files
authored
feat: fix project governance exposures issue and add integration name option enhancement (#65)
* refactor: replace CatalogV1 import with custom implementation and update catalog loading logic * fix: update exposure config handling in ManifestV12Wrapper to use AltimateExposureConfig * feat: add functionality to resolve integration names to IDs and enhance onboarding options in CLI * Bump version: 0.0.22 → 0.0.23 and update relevant files to reflect the new version. * refactor: update import paths for Catalog and CatalogV1 to reflect new schema structure
1 parent 01e6a25 commit ba6e383

File tree

15 files changed

+90
-22
lines changed

15 files changed

+90
-22
lines changed

.bumpversion.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[bumpversion]
2-
current_version = 0.0.21
2+
current_version = 0.0.23
33
commit = True
44
tag = True
55

docs/conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
year = "2024"
1616
author = "Altimate Inc."
1717
copyright = f"{year}, {author}"
18-
version = release = "0.0.21"
18+
version = release = "0.0.23"
1919

2020
pygments_style = "trac"
2121
templates_path = ["."]

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ def read(*names, **kwargs):
1313

1414
setup(
1515
name="altimate-datapilot-cli",
16-
version="0.0.22",
16+
version="0.0.23",
1717
license="MIT",
1818
description="Assistant for Data Teams",
1919
long_description="{}\n{}".format(

src/datapilot/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "0.0.21"
1+
__version__ = "0.0.23"

src/datapilot/clients/altimate/client.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,3 +110,8 @@ def get_all_dbt_configs(self):
110110
endpoint = "/dbtconfig/"
111111
params = {"size": 100}
112112
return self.get(endpoint, params=params)
113+
114+
def get_all_integrations(self):
115+
"""Get all integrations"""
116+
endpoint = "/dbt/v1/project_integrations/"
117+
return self.get(endpoint)

src/datapilot/clients/altimate/utils.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,3 +134,28 @@ def get_all_dbt_configs(
134134
"""Get all DBT configs from the API."""
135135
api_client = APIClient(api_token=api_token, base_url=backend_url, tenant=tenant)
136136
return api_client.get_all_dbt_configs()
137+
138+
139+
def get_all_integrations(
140+
api_token,
141+
tenant,
142+
backend_url,
143+
):
144+
"""Get all integrations from the API."""
145+
api_client = APIClient(api_token=api_token, base_url=backend_url, tenant=tenant)
146+
return api_client.get_all_integrations()
147+
148+
149+
def resolve_integration_name_to_id(
150+
integration_name,
151+
api_token,
152+
tenant,
153+
backend_url,
154+
):
155+
"""Resolve integration name to ID."""
156+
integrations = get_all_integrations(api_token, tenant, backend_url)
157+
if integrations:
158+
matching_integrations = [i for i in integrations if i.get("name") == integration_name]
159+
if matching_integrations:
160+
return matching_integrations[0].get("id")
161+
return None

src/datapilot/core/platforms/dbt/cli/cli.py

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from datapilot.clients.altimate.utils import check_token_and_instance
77
from datapilot.clients.altimate.utils import get_all_dbt_configs
88
from datapilot.clients.altimate.utils import onboard_file
9+
from datapilot.clients.altimate.utils import resolve_integration_name_to_id
910
from datapilot.clients.altimate.utils import start_dbt_ingestion
1011
from datapilot.clients.altimate.utils import validate_credentials
1112
from datapilot.clients.altimate.utils import validate_permissions
@@ -136,9 +137,14 @@ def project_health(
136137
"--dbt_core_integration_id",
137138
"--dbt_integration_id",
138139
"dbt_integration_id", # This is the parameter name that will be passed to the function
139-
prompt="DBT Integration ID",
140140
help="DBT Core Integration ID or DBT Integration ID",
141141
)
142+
@click.option(
143+
"--dbt_core_integration_name",
144+
"--dbt_integration_name",
145+
"dbt_integration_name", # This is the parameter name that will be passed to the function
146+
help="DBT Core Integration Name or DBT Integration Name (alternative to ID)",
147+
)
142148
@click.option(
143149
"--dbt_core_integration_environment",
144150
"--dbt_integration_environment",
@@ -154,11 +160,12 @@ def onboard(
154160
instance_name,
155161
backend_url,
156162
dbt_integration_id,
163+
dbt_integration_name,
157164
dbt_integration_environment,
158165
manifest_path,
159166
catalog_path,
160167
):
161-
"""Onboard a manifest file to DBT."""
168+
"""Onboard a manifest file to DBT. You can specify either --dbt_integration_id or --dbt_integration_name."""
162169

163170
# For onboard command, token and instance_name are required
164171
if not token:
@@ -176,6 +183,21 @@ def onboard(
176183
click.echo("Error: You don't have permission to perform this action.")
177184
return
178185

186+
# Resolve integration name to ID if name is provided instead of ID
187+
if not dbt_integration_id and not dbt_integration_name:
188+
dbt_integration_id = click.prompt("DBT Integration ID")
189+
elif dbt_integration_name and not dbt_integration_id:
190+
click.echo(f"Resolving integration name '{dbt_integration_name}' to ID...")
191+
resolved_id = resolve_integration_name_to_id(dbt_integration_name, token, instance_name, backend_url)
192+
if resolved_id:
193+
dbt_integration_id = resolved_id
194+
click.echo(f"Found integration ID: {dbt_integration_id}")
195+
else:
196+
click.echo(f"Error: Integration with name '{dbt_integration_name}' not found.")
197+
return
198+
elif dbt_integration_name and dbt_integration_id:
199+
click.echo("Warning: Both integration ID and name provided. Using ID and ignoring name.")
200+
179201
try:
180202
load_manifest(manifest_path)
181203
except Exception as e:

src/datapilot/core/platforms/dbt/executor.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from datapilot.core.platforms.dbt.insights import INSIGHTS
1616
from datapilot.core.platforms.dbt.insights.schema import DBTInsightResult
1717
from datapilot.core.platforms.dbt.insights.schema import DBTModelInsightResponse
18-
from datapilot.core.platforms.dbt.schemas.manifest import Catalog
18+
from datapilot.core.platforms.dbt.schemas.catalog import Catalog
1919
from datapilot.core.platforms.dbt.schemas.manifest import Manifest
2020
from datapilot.core.platforms.dbt.utils import get_models
2121
from datapilot.utils.formatting.utils import RED

src/datapilot/core/platforms/dbt/factory.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
from dbt_artifacts_parser.parsers.catalog.catalog_v1 import CatalogV1
1+
# Remove the import of CatalogV1 from dbt_artifacts_parser since we use our custom version
22
from dbt_artifacts_parser.parsers.manifest.manifest_v10 import ManifestV10
33
from dbt_artifacts_parser.parsers.manifest.manifest_v11 import ManifestV11
44
from dbt_artifacts_parser.parsers.manifest.manifest_v12 import ManifestV12
55

6-
from datapilot.core.platforms.dbt.schemas.manifest import Catalog
6+
from datapilot.core.platforms.dbt.schemas.catalog import Catalog
7+
from datapilot.core.platforms.dbt.schemas.catalog import CatalogV1
78
from datapilot.core.platforms.dbt.schemas.manifest import Manifest
89
from datapilot.core.platforms.dbt.wrappers.catalog.v1.wrapper import CatalogV1Wrapper
910
from datapilot.core.platforms.dbt.wrappers.manifest.v10.wrapper import ManifestV10Wrapper

src/datapilot/core/platforms/dbt/schemas/catalog.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
from typing import Optional
66
from typing import Union
77

8+
from dbt_artifacts_parser.parsers.catalog.catalog_v1 import CatalogV1 as BaseCatalogV1
9+
from dbt_artifacts_parser.parsers.catalog.catalog_v1 import Metadata as BaseMetadata
810
from pydantic.main import BaseModel
911

1012

@@ -52,3 +54,19 @@ class AltimateCatalogCatalogV1(BaseModel):
5254
nodes: Dict[str, AltimateCatalogTable]
5355
sources: Dict[str, AltimateCatalogTable]
5456
errors: Optional[Optional[List[str]]] = None
57+
58+
59+
# Custom classes to handle extra fields in newer dbt versions
60+
class Metadata(BaseMetadata):
61+
class Config:
62+
extra = "allow" # Allow extra fields in metadata
63+
64+
65+
class CatalogV1(BaseCatalogV1):
66+
metadata: Metadata # Use our custom metadata class
67+
68+
class Config:
69+
extra = "allow" # Allow extra fields
70+
71+
72+
Catalog = CatalogV1

0 commit comments

Comments
 (0)