collibra-connector 1.0.19__py3-none-any.whl → 1.1.1__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.
- collibra_connector/__init__.py +284 -4
- collibra_connector/api/Asset.py +301 -3
- collibra_connector/api/Attribute.py +204 -0
- collibra_connector/api/Base.py +2 -2
- collibra_connector/api/Relation.py +216 -0
- collibra_connector/api/Responsibility.py +5 -5
- collibra_connector/api/Search.py +102 -0
- collibra_connector/api/Workflow.py +50 -16
- collibra_connector/api/__init__.py +23 -13
- collibra_connector/async_connector.py +930 -0
- collibra_connector/cli.py +597 -0
- collibra_connector/connector.py +270 -48
- collibra_connector/helpers.py +845 -0
- collibra_connector/lineage.py +716 -0
- collibra_connector/models.py +897 -0
- collibra_connector/py.typed +0 -0
- collibra_connector/telemetry.py +576 -0
- collibra_connector/testing.py +806 -0
- collibra_connector-1.1.1.dist-info/METADATA +540 -0
- collibra_connector-1.1.1.dist-info/RECORD +32 -0
- {collibra_connector-1.0.19.dist-info → collibra_connector-1.1.1.dist-info}/WHEEL +1 -1
- collibra_connector-1.1.1.dist-info/entry_points.txt +2 -0
- collibra_connector-1.0.19.dist-info/METADATA +0 -157
- collibra_connector-1.0.19.dist-info/RECORD +0 -21
- {collibra_connector-1.0.19.dist-info → collibra_connector-1.1.1.dist-info}/licenses/LICENSE +0 -0
- {collibra_connector-1.0.19.dist-info → collibra_connector-1.1.1.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,597 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Command-Line Interface for Collibra Connector.
|
|
3
|
+
|
|
4
|
+
This module provides a CLI tool for interacting with Collibra
|
|
5
|
+
directly from the terminal without writing code.
|
|
6
|
+
|
|
7
|
+
Installation:
|
|
8
|
+
pip install collibra-connector[cli]
|
|
9
|
+
|
|
10
|
+
Usage:
|
|
11
|
+
collibra-sdk --help
|
|
12
|
+
collibra-sdk search "Business Term" --format json
|
|
13
|
+
collibra-sdk export-domain --id "uuid" --output report.csv
|
|
14
|
+
collibra-sdk get-asset --id "uuid"
|
|
15
|
+
"""
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
import csv
|
|
19
|
+
import json
|
|
20
|
+
import os
|
|
21
|
+
import sys
|
|
22
|
+
from typing import Any, Dict, List, Optional
|
|
23
|
+
|
|
24
|
+
try:
|
|
25
|
+
import click
|
|
26
|
+
CLICK_AVAILABLE = True
|
|
27
|
+
except ImportError:
|
|
28
|
+
CLICK_AVAILABLE = False
|
|
29
|
+
|
|
30
|
+
if CLICK_AVAILABLE:
|
|
31
|
+
from click import Context, echo, style, secho
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def get_connector():
|
|
35
|
+
"""Create connector from environment variables."""
|
|
36
|
+
from .connector import CollibraConnector
|
|
37
|
+
|
|
38
|
+
api = os.environ.get("COLLIBRA_URL")
|
|
39
|
+
username = os.environ.get("COLLIBRA_USERNAME")
|
|
40
|
+
password = os.environ.get("COLLIBRA_PASSWORD")
|
|
41
|
+
|
|
42
|
+
if not all([api, username, password]):
|
|
43
|
+
raise click.ClickException(
|
|
44
|
+
"Missing environment variables. Set:\n"
|
|
45
|
+
" COLLIBRA_URL=https://your-instance.collibra.com\n"
|
|
46
|
+
" COLLIBRA_USERNAME=your-username\n"
|
|
47
|
+
" COLLIBRA_PASSWORD=your-password"
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
return CollibraConnector(api=api, username=username, password=password)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def format_output(data: Any, fmt: str) -> str:
|
|
54
|
+
"""Format output data based on format type."""
|
|
55
|
+
if fmt == "json":
|
|
56
|
+
return json.dumps(data, indent=2, default=str)
|
|
57
|
+
elif fmt == "table":
|
|
58
|
+
if isinstance(data, list) and data:
|
|
59
|
+
# Simple table format
|
|
60
|
+
headers = list(data[0].keys())
|
|
61
|
+
lines = ["\t".join(headers)]
|
|
62
|
+
for item in data:
|
|
63
|
+
lines.append("\t".join(str(item.get(h, "")) for h in headers))
|
|
64
|
+
return "\n".join(lines)
|
|
65
|
+
return str(data)
|
|
66
|
+
elif fmt == "csv":
|
|
67
|
+
if isinstance(data, list) and data:
|
|
68
|
+
import io
|
|
69
|
+
output = io.StringIO()
|
|
70
|
+
writer = csv.DictWriter(output, fieldnames=data[0].keys())
|
|
71
|
+
writer.writeheader()
|
|
72
|
+
writer.writerows(data)
|
|
73
|
+
return output.getvalue()
|
|
74
|
+
return str(data)
|
|
75
|
+
else:
|
|
76
|
+
return str(data)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
if CLICK_AVAILABLE:
|
|
80
|
+
@click.group()
|
|
81
|
+
@click.version_option(version="1.1.0", prog_name="collibra-sdk")
|
|
82
|
+
@click.pass_context
|
|
83
|
+
def cli(ctx: Context) -> None:
|
|
84
|
+
"""
|
|
85
|
+
Collibra SDK - Command line interface for Collibra Data Governance.
|
|
86
|
+
|
|
87
|
+
Configure connection using environment variables:
|
|
88
|
+
|
|
89
|
+
export COLLIBRA_URL=https://your-instance.collibra.com
|
|
90
|
+
|
|
91
|
+
export COLLIBRA_USERNAME=your-username
|
|
92
|
+
|
|
93
|
+
export COLLIBRA_PASSWORD=your-password
|
|
94
|
+
"""
|
|
95
|
+
ctx.ensure_object(dict)
|
|
96
|
+
|
|
97
|
+
# ==========================================================================
|
|
98
|
+
# Connection Commands
|
|
99
|
+
# ==========================================================================
|
|
100
|
+
|
|
101
|
+
@cli.command("test")
|
|
102
|
+
def test_connection() -> None:
|
|
103
|
+
"""Test the connection to Collibra."""
|
|
104
|
+
try:
|
|
105
|
+
conn = get_connector()
|
|
106
|
+
if conn.test_connection():
|
|
107
|
+
secho("Connection successful!", fg="green")
|
|
108
|
+
else:
|
|
109
|
+
secho("Connection failed.", fg="red")
|
|
110
|
+
sys.exit(1)
|
|
111
|
+
except Exception as e:
|
|
112
|
+
secho(f"Error: {e}", fg="red")
|
|
113
|
+
sys.exit(1)
|
|
114
|
+
|
|
115
|
+
@cli.command("info")
|
|
116
|
+
def show_info() -> None:
|
|
117
|
+
"""Show connection and version information."""
|
|
118
|
+
try:
|
|
119
|
+
conn = get_connector()
|
|
120
|
+
echo(f"Collibra URL: {conn.base_url}")
|
|
121
|
+
echo(f"SDK Version: {conn.get_version()}")
|
|
122
|
+
|
|
123
|
+
if conn.test_connection():
|
|
124
|
+
secho("Status: Connected", fg="green")
|
|
125
|
+
else:
|
|
126
|
+
secho("Status: Not Connected", fg="red")
|
|
127
|
+
except Exception as e:
|
|
128
|
+
secho(f"Error: {e}", fg="red")
|
|
129
|
+
sys.exit(1)
|
|
130
|
+
|
|
131
|
+
# ==========================================================================
|
|
132
|
+
# Search Commands
|
|
133
|
+
# ==========================================================================
|
|
134
|
+
|
|
135
|
+
@cli.command("search")
|
|
136
|
+
@click.argument("query")
|
|
137
|
+
@click.option("--type", "-t", "asset_type", help="Filter by asset type name")
|
|
138
|
+
@click.option("--domain", "-d", "domain_id", help="Filter by domain ID")
|
|
139
|
+
@click.option("--community", "-c", "community_id", help="Filter by community ID")
|
|
140
|
+
@click.option("--limit", "-l", default=10, help="Maximum results (default: 10)")
|
|
141
|
+
@click.option("--format", "-f", "fmt", default="table",
|
|
142
|
+
type=click.Choice(["json", "table", "csv"]),
|
|
143
|
+
help="Output format")
|
|
144
|
+
def search_assets(
|
|
145
|
+
query: str,
|
|
146
|
+
asset_type: Optional[str],
|
|
147
|
+
domain_id: Optional[str],
|
|
148
|
+
community_id: Optional[str],
|
|
149
|
+
limit: int,
|
|
150
|
+
fmt: str
|
|
151
|
+
) -> None:
|
|
152
|
+
"""
|
|
153
|
+
Search for assets in Collibra.
|
|
154
|
+
|
|
155
|
+
Examples:
|
|
156
|
+
|
|
157
|
+
collibra-sdk search "Customer"
|
|
158
|
+
|
|
159
|
+
collibra-sdk search "Product*" --limit 50 --format json
|
|
160
|
+
|
|
161
|
+
collibra-sdk search "Order" --type "Business Term"
|
|
162
|
+
"""
|
|
163
|
+
try:
|
|
164
|
+
conn = get_connector()
|
|
165
|
+
|
|
166
|
+
# Prepare filters
|
|
167
|
+
type_ids = None
|
|
168
|
+
if asset_type:
|
|
169
|
+
# Look up type ID by name
|
|
170
|
+
types = conn.metadata.get_asset_types(name=asset_type, limit=1)
|
|
171
|
+
if types.get("results"):
|
|
172
|
+
type_ids = [types["results"][0]["id"]]
|
|
173
|
+
else:
|
|
174
|
+
secho(f"Asset type not found: {asset_type}", fg="yellow")
|
|
175
|
+
|
|
176
|
+
domain_ids = [domain_id] if domain_id else None
|
|
177
|
+
community_ids = [community_id] if community_id else None
|
|
178
|
+
|
|
179
|
+
# Execute search
|
|
180
|
+
result = conn.search.find_assets(
|
|
181
|
+
query=query,
|
|
182
|
+
limit=limit,
|
|
183
|
+
type_ids=type_ids,
|
|
184
|
+
domain_ids=domain_ids,
|
|
185
|
+
community_ids=community_ids
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
# Format results
|
|
189
|
+
items = []
|
|
190
|
+
for item in result.get("results", []):
|
|
191
|
+
resource = item.get("resource", {})
|
|
192
|
+
items.append({
|
|
193
|
+
"id": resource.get("id"),
|
|
194
|
+
"name": resource.get("name") or resource.get("displayName"),
|
|
195
|
+
"type": resource.get("resourceType"),
|
|
196
|
+
"score": item.get("score", 0)
|
|
197
|
+
})
|
|
198
|
+
|
|
199
|
+
if not items:
|
|
200
|
+
echo("No results found.")
|
|
201
|
+
return
|
|
202
|
+
|
|
203
|
+
echo(f"Found {result.get('total', 0)} results (showing {len(items)}):\n")
|
|
204
|
+
echo(format_output(items, fmt))
|
|
205
|
+
|
|
206
|
+
except Exception as e:
|
|
207
|
+
secho(f"Error: {e}", fg="red")
|
|
208
|
+
sys.exit(1)
|
|
209
|
+
|
|
210
|
+
# ==========================================================================
|
|
211
|
+
# Asset Commands
|
|
212
|
+
# ==========================================================================
|
|
213
|
+
|
|
214
|
+
@cli.command("get-asset")
|
|
215
|
+
@click.option("--id", "asset_id", required=True, help="Asset UUID")
|
|
216
|
+
@click.option("--format", "-f", "fmt", default="json",
|
|
217
|
+
type=click.Choice(["json", "table"]),
|
|
218
|
+
help="Output format")
|
|
219
|
+
@click.option("--full", is_flag=True, help="Include attributes and relations")
|
|
220
|
+
def get_asset(asset_id: str, fmt: str, full: bool) -> None:
|
|
221
|
+
"""
|
|
222
|
+
Get details for a specific asset.
|
|
223
|
+
|
|
224
|
+
Examples:
|
|
225
|
+
|
|
226
|
+
collibra-sdk get-asset --id "abc-123-uuid"
|
|
227
|
+
|
|
228
|
+
collibra-sdk get-asset --id "abc-123-uuid" --full
|
|
229
|
+
"""
|
|
230
|
+
try:
|
|
231
|
+
conn = get_connector()
|
|
232
|
+
|
|
233
|
+
if full:
|
|
234
|
+
result = conn.asset.get_full_profile(asset_id)
|
|
235
|
+
# Flatten for display
|
|
236
|
+
output = {
|
|
237
|
+
"id": result["asset"].get("id"),
|
|
238
|
+
"name": result["asset"].get("name"),
|
|
239
|
+
"display_name": result["asset"].get("displayName"),
|
|
240
|
+
"type": result["asset"].get("type", {}).get("name"),
|
|
241
|
+
"status": result["asset"].get("status", {}).get("name"),
|
|
242
|
+
"domain": result["asset"].get("domain", {}).get("name"),
|
|
243
|
+
"attributes": result.get("attributes", {}),
|
|
244
|
+
"relations_outgoing": result["relations"].get("outgoing_count", 0),
|
|
245
|
+
"relations_incoming": result["relations"].get("incoming_count", 0),
|
|
246
|
+
"responsibilities": result.get("responsibilities", [])
|
|
247
|
+
}
|
|
248
|
+
else:
|
|
249
|
+
output = conn.asset.get_asset(asset_id)
|
|
250
|
+
|
|
251
|
+
echo(format_output(output, fmt))
|
|
252
|
+
|
|
253
|
+
except Exception as e:
|
|
254
|
+
secho(f"Error: {e}", fg="red")
|
|
255
|
+
sys.exit(1)
|
|
256
|
+
|
|
257
|
+
@cli.command("list-assets")
|
|
258
|
+
@click.option("--domain", "-d", "domain_id", help="Filter by domain ID")
|
|
259
|
+
@click.option("--community", "-c", "community_id", help="Filter by community ID")
|
|
260
|
+
@click.option("--type", "-t", "type_ids", multiple=True, help="Filter by type ID(s)")
|
|
261
|
+
@click.option("--limit", "-l", default=100, help="Maximum results")
|
|
262
|
+
@click.option("--format", "-f", "fmt", default="table",
|
|
263
|
+
type=click.Choice(["json", "table", "csv"]),
|
|
264
|
+
help="Output format")
|
|
265
|
+
def list_assets(
|
|
266
|
+
domain_id: Optional[str],
|
|
267
|
+
community_id: Optional[str],
|
|
268
|
+
type_ids: tuple,
|
|
269
|
+
limit: int,
|
|
270
|
+
fmt: str
|
|
271
|
+
) -> None:
|
|
272
|
+
"""
|
|
273
|
+
List assets with optional filters.
|
|
274
|
+
|
|
275
|
+
Examples:
|
|
276
|
+
|
|
277
|
+
collibra-sdk list-assets --domain "uuid"
|
|
278
|
+
|
|
279
|
+
collibra-sdk list-assets --limit 50 --format csv > assets.csv
|
|
280
|
+
"""
|
|
281
|
+
try:
|
|
282
|
+
conn = get_connector()
|
|
283
|
+
|
|
284
|
+
result = conn.asset.find_assets(
|
|
285
|
+
domain_id=domain_id,
|
|
286
|
+
community_id=community_id,
|
|
287
|
+
asset_type_ids=list(type_ids) if type_ids else None,
|
|
288
|
+
limit=limit
|
|
289
|
+
)
|
|
290
|
+
|
|
291
|
+
items = []
|
|
292
|
+
for asset in result.get("results", []):
|
|
293
|
+
items.append({
|
|
294
|
+
"id": asset.get("id"),
|
|
295
|
+
"name": asset.get("name"),
|
|
296
|
+
"type": asset.get("type", {}).get("name"),
|
|
297
|
+
"status": asset.get("status", {}).get("name"),
|
|
298
|
+
"domain": asset.get("domain", {}).get("name")
|
|
299
|
+
})
|
|
300
|
+
|
|
301
|
+
echo(f"Total: {result.get('total', 0)} assets\n")
|
|
302
|
+
echo(format_output(items, fmt))
|
|
303
|
+
|
|
304
|
+
except Exception as e:
|
|
305
|
+
secho(f"Error: {e}", fg="red")
|
|
306
|
+
sys.exit(1)
|
|
307
|
+
|
|
308
|
+
# ==========================================================================
|
|
309
|
+
# Export Commands
|
|
310
|
+
# ==========================================================================
|
|
311
|
+
|
|
312
|
+
@cli.command("export-domain")
|
|
313
|
+
@click.option("--id", "domain_id", required=True, help="Domain UUID")
|
|
314
|
+
@click.option("--output", "-o", "output_file", required=True,
|
|
315
|
+
help="Output file path (.csv or .json)")
|
|
316
|
+
@click.option("--include-attributes", is_flag=True, default=True,
|
|
317
|
+
help="Include asset attributes")
|
|
318
|
+
@click.option("--include-relations", is_flag=True, default=False,
|
|
319
|
+
help="Include relation summaries")
|
|
320
|
+
@click.option("--limit", "-l", default=1000, help="Maximum assets to export")
|
|
321
|
+
def export_domain(
|
|
322
|
+
domain_id: str,
|
|
323
|
+
output_file: str,
|
|
324
|
+
include_attributes: bool,
|
|
325
|
+
include_relations: bool,
|
|
326
|
+
limit: int
|
|
327
|
+
) -> None:
|
|
328
|
+
"""
|
|
329
|
+
Export all assets in a domain to a file.
|
|
330
|
+
|
|
331
|
+
Examples:
|
|
332
|
+
|
|
333
|
+
collibra-sdk export-domain --id "uuid" --output assets.csv
|
|
334
|
+
|
|
335
|
+
collibra-sdk export-domain --id "uuid" --output data.json --include-relations
|
|
336
|
+
"""
|
|
337
|
+
try:
|
|
338
|
+
from .helpers import DataFrameExporter
|
|
339
|
+
|
|
340
|
+
conn = get_connector()
|
|
341
|
+
exporter = DataFrameExporter(conn)
|
|
342
|
+
|
|
343
|
+
echo(f"Exporting domain {domain_id}...")
|
|
344
|
+
|
|
345
|
+
df = exporter.assets_to_dataframe(
|
|
346
|
+
domain_id=domain_id,
|
|
347
|
+
limit=limit,
|
|
348
|
+
include_attributes=include_attributes,
|
|
349
|
+
include_relations=include_relations
|
|
350
|
+
)
|
|
351
|
+
|
|
352
|
+
if output_file.endswith(".csv"):
|
|
353
|
+
df.to_csv(output_file, index=False)
|
|
354
|
+
elif output_file.endswith(".json"):
|
|
355
|
+
df.to_json(output_file, orient="records", indent=2)
|
|
356
|
+
elif output_file.endswith(".xlsx"):
|
|
357
|
+
df.to_excel(output_file, index=False)
|
|
358
|
+
else:
|
|
359
|
+
df.to_csv(output_file, index=False)
|
|
360
|
+
|
|
361
|
+
secho(f"Exported {len(df)} assets to {output_file}", fg="green")
|
|
362
|
+
|
|
363
|
+
except ImportError:
|
|
364
|
+
secho("Pandas is required for export. Install with: pip install pandas", fg="red")
|
|
365
|
+
sys.exit(1)
|
|
366
|
+
except Exception as e:
|
|
367
|
+
secho(f"Error: {e}", fg="red")
|
|
368
|
+
sys.exit(1)
|
|
369
|
+
|
|
370
|
+
@cli.command("export-community")
|
|
371
|
+
@click.option("--id", "community_id", required=True, help="Community UUID")
|
|
372
|
+
@click.option("--output", "-o", "output_file", required=True,
|
|
373
|
+
help="Output file path")
|
|
374
|
+
@click.option("--include-attributes", is_flag=True, default=True)
|
|
375
|
+
@click.option("--limit", "-l", default=1000)
|
|
376
|
+
def export_community(
|
|
377
|
+
community_id: str,
|
|
378
|
+
output_file: str,
|
|
379
|
+
include_attributes: bool,
|
|
380
|
+
limit: int
|
|
381
|
+
) -> None:
|
|
382
|
+
"""
|
|
383
|
+
Export all assets in a community to a file.
|
|
384
|
+
|
|
385
|
+
Examples:
|
|
386
|
+
|
|
387
|
+
collibra-sdk export-community --id "uuid" --output assets.csv
|
|
388
|
+
"""
|
|
389
|
+
try:
|
|
390
|
+
from .helpers import DataFrameExporter
|
|
391
|
+
|
|
392
|
+
conn = get_connector()
|
|
393
|
+
exporter = DataFrameExporter(conn)
|
|
394
|
+
|
|
395
|
+
echo(f"Exporting community {community_id}...")
|
|
396
|
+
|
|
397
|
+
df = exporter.assets_to_dataframe(
|
|
398
|
+
community_id=community_id,
|
|
399
|
+
limit=limit,
|
|
400
|
+
include_attributes=include_attributes
|
|
401
|
+
)
|
|
402
|
+
|
|
403
|
+
if output_file.endswith(".csv"):
|
|
404
|
+
df.to_csv(output_file, index=False)
|
|
405
|
+
elif output_file.endswith(".json"):
|
|
406
|
+
df.to_json(output_file, orient="records", indent=2)
|
|
407
|
+
else:
|
|
408
|
+
df.to_csv(output_file, index=False)
|
|
409
|
+
|
|
410
|
+
secho(f"Exported {len(df)} assets to {output_file}", fg="green")
|
|
411
|
+
|
|
412
|
+
except ImportError:
|
|
413
|
+
secho("Pandas required. Install with: pip install pandas", fg="red")
|
|
414
|
+
sys.exit(1)
|
|
415
|
+
except Exception as e:
|
|
416
|
+
secho(f"Error: {e}", fg="red")
|
|
417
|
+
sys.exit(1)
|
|
418
|
+
|
|
419
|
+
# ==========================================================================
|
|
420
|
+
# Community/Domain Commands
|
|
421
|
+
# ==========================================================================
|
|
422
|
+
|
|
423
|
+
@cli.command("list-communities")
|
|
424
|
+
@click.option("--format", "-f", "fmt", default="table",
|
|
425
|
+
type=click.Choice(["json", "table", "csv"]))
|
|
426
|
+
@click.option("--limit", "-l", default=100)
|
|
427
|
+
def list_communities(fmt: str, limit: int) -> None:
|
|
428
|
+
"""List all communities."""
|
|
429
|
+
try:
|
|
430
|
+
conn = get_connector()
|
|
431
|
+
result = conn.community.find_communities(limit=limit)
|
|
432
|
+
|
|
433
|
+
items = []
|
|
434
|
+
for comm in result.get("results", []):
|
|
435
|
+
items.append({
|
|
436
|
+
"id": comm.get("id"),
|
|
437
|
+
"name": comm.get("name"),
|
|
438
|
+
"description": (comm.get("description") or "")[:50],
|
|
439
|
+
"parent": comm.get("parent", {}).get("name") if comm.get("parent") else None
|
|
440
|
+
})
|
|
441
|
+
|
|
442
|
+
echo(f"Total: {result.get('total', 0)} communities\n")
|
|
443
|
+
echo(format_output(items, fmt))
|
|
444
|
+
|
|
445
|
+
except Exception as e:
|
|
446
|
+
secho(f"Error: {e}", fg="red")
|
|
447
|
+
sys.exit(1)
|
|
448
|
+
|
|
449
|
+
@cli.command("list-domains")
|
|
450
|
+
@click.option("--community", "-c", "community_id", help="Filter by community ID")
|
|
451
|
+
@click.option("--format", "-f", "fmt", default="table",
|
|
452
|
+
type=click.Choice(["json", "table", "csv"]))
|
|
453
|
+
@click.option("--limit", "-l", default=100)
|
|
454
|
+
def list_domains(community_id: Optional[str], fmt: str, limit: int) -> None:
|
|
455
|
+
"""List all domains."""
|
|
456
|
+
try:
|
|
457
|
+
conn = get_connector()
|
|
458
|
+
result = conn.domain.find_domains(community_id=community_id, limit=limit)
|
|
459
|
+
|
|
460
|
+
items = []
|
|
461
|
+
for domain in result.get("results", []):
|
|
462
|
+
items.append({
|
|
463
|
+
"id": domain.get("id"),
|
|
464
|
+
"name": domain.get("name"),
|
|
465
|
+
"type": domain.get("type", {}).get("name"),
|
|
466
|
+
"community": domain.get("community", {}).get("name")
|
|
467
|
+
})
|
|
468
|
+
|
|
469
|
+
echo(f"Total: {result.get('total', 0)} domains\n")
|
|
470
|
+
echo(format_output(items, fmt))
|
|
471
|
+
|
|
472
|
+
except Exception as e:
|
|
473
|
+
secho(f"Error: {e}", fg="red")
|
|
474
|
+
sys.exit(1)
|
|
475
|
+
|
|
476
|
+
# ==========================================================================
|
|
477
|
+
# Metadata Commands
|
|
478
|
+
# ==========================================================================
|
|
479
|
+
|
|
480
|
+
@cli.command("list-asset-types")
|
|
481
|
+
@click.option("--format", "-f", "fmt", default="table",
|
|
482
|
+
type=click.Choice(["json", "table", "csv"]))
|
|
483
|
+
@click.option("--limit", "-l", default=100)
|
|
484
|
+
def list_asset_types(fmt: str, limit: int) -> None:
|
|
485
|
+
"""List all asset types."""
|
|
486
|
+
try:
|
|
487
|
+
conn = get_connector()
|
|
488
|
+
result = conn.metadata.get_asset_types()
|
|
489
|
+
|
|
490
|
+
items = []
|
|
491
|
+
for at in result.get("results", [])[:limit]: # Apply limit manually
|
|
492
|
+
items.append({
|
|
493
|
+
"id": at.get("id"),
|
|
494
|
+
"name": at.get("name"),
|
|
495
|
+
"public_id": at.get("publicId"),
|
|
496
|
+
"description": (at.get("description") or "")[:40]
|
|
497
|
+
})
|
|
498
|
+
|
|
499
|
+
echo(f"Total: {result.get('total', 0)} asset types (showing {len(items)})\n")
|
|
500
|
+
echo(format_output(items, fmt))
|
|
501
|
+
|
|
502
|
+
except Exception as e:
|
|
503
|
+
secho(f"Error: {e}", fg="red")
|
|
504
|
+
sys.exit(1)
|
|
505
|
+
|
|
506
|
+
@cli.command("list-statuses")
|
|
507
|
+
@click.option("--format", "-f", "fmt", default="table",
|
|
508
|
+
type=click.Choice(["json", "table", "csv"]))
|
|
509
|
+
def list_statuses(fmt: str) -> None:
|
|
510
|
+
"""List all statuses."""
|
|
511
|
+
try:
|
|
512
|
+
conn = get_connector()
|
|
513
|
+
result = conn.metadata.get_statuses()
|
|
514
|
+
|
|
515
|
+
items = []
|
|
516
|
+
for status in result.get("results", []):
|
|
517
|
+
items.append({
|
|
518
|
+
"id": status.get("id"),
|
|
519
|
+
"name": status.get("name"),
|
|
520
|
+
"description": (status.get("description") or "")[:40]
|
|
521
|
+
})
|
|
522
|
+
|
|
523
|
+
echo(format_output(items, fmt))
|
|
524
|
+
|
|
525
|
+
except Exception as e:
|
|
526
|
+
secho(f"Error: {e}", fg="red")
|
|
527
|
+
sys.exit(1)
|
|
528
|
+
|
|
529
|
+
# ==========================================================================
|
|
530
|
+
# Bulk Operations
|
|
531
|
+
# ==========================================================================
|
|
532
|
+
|
|
533
|
+
@cli.command("bulk-update-status")
|
|
534
|
+
@click.option("--input", "-i", "input_file", required=True,
|
|
535
|
+
help="CSV file with 'id' column")
|
|
536
|
+
@click.option("--status-id", required=True, help="New status UUID")
|
|
537
|
+
@click.option("--dry-run", is_flag=True, help="Preview without making changes")
|
|
538
|
+
def bulk_update_status(input_file: str, status_id: str, dry_run: bool) -> None:
|
|
539
|
+
"""
|
|
540
|
+
Update status for multiple assets from a CSV file.
|
|
541
|
+
|
|
542
|
+
The input file should have an 'id' column with asset UUIDs.
|
|
543
|
+
|
|
544
|
+
Examples:
|
|
545
|
+
|
|
546
|
+
collibra-sdk bulk-update-status --input assets.csv --status-id "uuid"
|
|
547
|
+
|
|
548
|
+
collibra-sdk bulk-update-status --input assets.csv --status-id "uuid" --dry-run
|
|
549
|
+
"""
|
|
550
|
+
try:
|
|
551
|
+
import pandas as pd
|
|
552
|
+
|
|
553
|
+
conn = get_connector()
|
|
554
|
+
df = pd.read_csv(input_file)
|
|
555
|
+
|
|
556
|
+
if "id" not in df.columns:
|
|
557
|
+
secho("Error: CSV must have an 'id' column", fg="red")
|
|
558
|
+
sys.exit(1)
|
|
559
|
+
|
|
560
|
+
asset_ids = df["id"].tolist()
|
|
561
|
+
echo(f"Found {len(asset_ids)} assets to update")
|
|
562
|
+
|
|
563
|
+
if dry_run:
|
|
564
|
+
echo("Dry run - no changes made")
|
|
565
|
+
return
|
|
566
|
+
|
|
567
|
+
success = 0
|
|
568
|
+
errors = 0
|
|
569
|
+
|
|
570
|
+
with click.progressbar(asset_ids, label="Updating assets") as bar:
|
|
571
|
+
for asset_id in bar:
|
|
572
|
+
try:
|
|
573
|
+
conn.asset.change_asset(asset_id=asset_id, status_id=status_id)
|
|
574
|
+
success += 1
|
|
575
|
+
except Exception:
|
|
576
|
+
errors += 1
|
|
577
|
+
|
|
578
|
+
secho(f"Updated: {success}, Errors: {errors}", fg="green" if errors == 0 else "yellow")
|
|
579
|
+
|
|
580
|
+
except ImportError:
|
|
581
|
+
secho("Pandas required. Install with: pip install pandas", fg="red")
|
|
582
|
+
sys.exit(1)
|
|
583
|
+
except Exception as e:
|
|
584
|
+
secho(f"Error: {e}", fg="red")
|
|
585
|
+
sys.exit(1)
|
|
586
|
+
|
|
587
|
+
|
|
588
|
+
def main() -> None:
|
|
589
|
+
"""Entry point for the CLI."""
|
|
590
|
+
if not CLICK_AVAILABLE:
|
|
591
|
+
print("CLI requires 'click' package. Install with: pip install click")
|
|
592
|
+
sys.exit(1)
|
|
593
|
+
cli()
|
|
594
|
+
|
|
595
|
+
|
|
596
|
+
if __name__ == "__main__":
|
|
597
|
+
main()
|