pvw-cli 1.2.2__py3-none-any.whl → 1.2.4__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 pvw-cli might be problematic. Click here for more details.

purviewcli/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
- __version__ = "1.2.2"
1
+ __version__ = "1.2.4"
2
2
 
3
3
  # Import main client modules
4
4
  from .client import *
@@ -24,4 +24,4 @@ __all__ = [
24
24
  "share",
25
25
  "collections",
26
26
  "uc",
27
- ]
27
+ ]
purviewcli/cli/lineage.py CHANGED
@@ -54,7 +54,7 @@ def lineage(ctx):
54
54
  def import_cmd(ctx, csv_file):
55
55
  """Import lineage relationships from CSV file (calls client lineageCSVProcess)."""
56
56
  try:
57
- if ctx.obj.get("mock"):
57
+ if ctx.obj and ctx.obj.get("mock"):
58
58
  console.print("[yellow][MOCK] lineage import command[/yellow]")
59
59
  console.print(f"[dim]File: {csv_file}[/dim]")
60
60
  console.print("[green]MOCK lineage import completed successfully[/green]")
@@ -68,6 +68,9 @@ def import_cmd(ctx, csv_file):
68
68
  console.print(json.dumps(result, indent=2))
69
69
  except Exception as e:
70
70
  console.print(f"[red]ERROR: Error executing lineage import: {str(e)}[/red]")
71
+ import traceback
72
+ if ctx.obj and ctx.obj.get("debug"):
73
+ console.print(f"[dim]{traceback.format_exc()}[/dim]")
71
74
 
72
75
 
73
76
  @lineage.command()
purviewcli/cli/search.py CHANGED
@@ -157,11 +157,17 @@ def _format_search_results(data, show_ids=False):
157
157
  # Handle collection - try multiple sources
158
158
  collection = 'N/A'
159
159
  if 'collection' in item and item['collection']:
160
- collection = item['collection'].get('name', 'N/A')
161
- elif 'collectionId' in item:
160
+ if isinstance(item['collection'], dict):
161
+ collection = item['collection'].get('name', 'N/A')
162
+ else:
163
+ collection = str(item['collection'])
164
+ elif 'collectionId' in item and item['collectionId']:
162
165
  collection = item.get('collectionId', 'N/A')
163
- elif 'assetName' in item:
164
- collection = item.get('assetName', 'N/A')
166
+ elif 'assetName' in item and item['assetName']:
167
+ # Try to extract collection from asset name
168
+ asset_name = item.get('assetName', '')
169
+ if asset_name and asset_name != 'N/A':
170
+ collection = asset_name
165
171
 
166
172
  # Build row data with ID always shown
167
173
  row_data = [name, entity_type, entity_id, collection, qualified_name]
@@ -209,20 +209,29 @@ class Lineage(Endpoint):
209
209
  # Read CSV file
210
210
  df = pd.read_csv(csv_file)
211
211
 
212
- # Validate required columns
213
- required_columns = ['source_qualified_name', 'target_qualified_name']
214
- missing_columns = [col for col in required_columns if col not in df.columns]
215
- if missing_columns:
216
- raise ValueError(f"Missing required columns: {missing_columns}")
212
+ # Determine which format is being used (GUID-based or qualified name-based)
213
+ has_guid_columns = 'source_entity_guid' in df.columns and 'target_entity_guid' in df.columns
214
+ has_qn_columns = 'source_qualified_name' in df.columns and 'target_qualified_name' in df.columns
215
+
216
+ if not has_guid_columns and not has_qn_columns:
217
+ raise ValueError(
218
+ "CSV must contain either (source_entity_guid, target_entity_guid) "
219
+ "or (source_qualified_name, target_qualified_name) columns"
220
+ )
217
221
 
218
222
  # Generate lineage entities and relationships
219
223
  lineage_entities = []
220
224
  lineage_relationships = []
221
225
 
222
- for _, row in df.iterrows():
226
+ for idx, row in df.iterrows():
223
227
  # Create process entity for each lineage relationship
224
228
  process_guid = str(uuid.uuid4())
225
- process_name = row.get('process_name', f"Process_{datetime.now().strftime('%Y%m%d_%H%M%S')}")
229
+ process_name = row.get('process_name', f"Process_{datetime.now().strftime('%Y%m%d_%H%M%S')}_{idx}")
230
+
231
+ # Clean GUIDs if present (remove guid= prefix and quotes)
232
+ if has_guid_columns:
233
+ source_guid = str(row['source_entity_guid']).strip().replace('guid=', '').strip('"')
234
+ target_guid = str(row['target_entity_guid']).strip().replace('guid=', '').strip('"')
226
235
 
227
236
  # Process entity
228
237
  process_entity = {
@@ -231,8 +240,8 @@ class Lineage(Endpoint):
231
240
  "attributes": {
232
241
  "qualifiedName": f"{process_name}@{args.get('--cluster', 'default')}",
233
242
  "name": process_name,
234
- "description": row.get('description', ''),
235
- "owner": row.get('owner', ''),
243
+ "description": str(row.get('description', '')),
244
+ "owner": str(row.get('owner', '')),
236
245
  },
237
246
  "classifications": [],
238
247
  "meanings": []
@@ -241,7 +250,7 @@ class Lineage(Endpoint):
241
250
  # Add custom attributes if present
242
251
  custom_attrs = ['confidence_score', 'metadata', 'tags']
243
252
  for attr in custom_attrs:
244
- if attr in row and pd.notna(row[attr]):
253
+ if attr in row and pd.notna(row[attr]) and str(row[attr]).strip():
245
254
  if attr == 'tags':
246
255
  process_entity["attributes"][attr] = str(row[attr]).split(',')
247
256
  elif attr == 'metadata':
@@ -254,41 +263,74 @@ class Lineage(Endpoint):
254
263
 
255
264
  lineage_entities.append(process_entity)
256
265
 
257
- # Input relationship (source -> process)
258
- input_relationship = {
259
- "guid": str(uuid.uuid4()),
260
- "typeName": "Process",
261
- "end1": {
262
- "guid": "-1", # Will be resolved by qualified name
263
- "typeName": row.get('source_type', 'DataSet'),
264
- "uniqueAttributes": {
265
- "qualifiedName": row['source_qualified_name']
266
- }
267
- },
268
- "end2": {
269
- "guid": process_guid,
270
- "typeName": "Process"
271
- },
272
- "label": "inputToProcesses"
273
- }
266
+ # Determine relationship type
267
+ relationship_type = str(row.get('relationship_type', 'Process')).strip() or 'Process'
274
268
 
275
- # Output relationship (process -> target)
276
- output_relationship = {
277
- "guid": str(uuid.uuid4()),
278
- "typeName": "Process",
279
- "end1": {
280
- "guid": process_guid,
281
- "typeName": "Process"
282
- },
283
- "end2": {
284
- "guid": "-1", # Will be resolved by qualified name
285
- "typeName": row.get('target_type', 'DataSet'),
286
- "uniqueAttributes": {
287
- "qualifiedName": row['target_qualified_name']
288
- }
289
- },
290
- "label": "outputFromProcesses"
291
- }
269
+ # Input relationship (source -> process)
270
+ if has_guid_columns:
271
+ input_relationship = {
272
+ "guid": str(uuid.uuid4()),
273
+ "typeName": relationship_type,
274
+ "end1": {
275
+ "guid": source_guid,
276
+ "typeName": row.get('source_type', 'DataSet')
277
+ },
278
+ "end2": {
279
+ "guid": process_guid,
280
+ "typeName": "Process"
281
+ },
282
+ "label": "inputToProcesses"
283
+ }
284
+
285
+ # Output relationship (process -> target)
286
+ output_relationship = {
287
+ "guid": str(uuid.uuid4()),
288
+ "typeName": relationship_type,
289
+ "end1": {
290
+ "guid": process_guid,
291
+ "typeName": "Process"
292
+ },
293
+ "end2": {
294
+ "guid": target_guid,
295
+ "typeName": row.get('target_type', 'DataSet')
296
+ },
297
+ "label": "outputFromProcesses"
298
+ }
299
+ else:
300
+ # Use qualified names
301
+ input_relationship = {
302
+ "guid": str(uuid.uuid4()),
303
+ "typeName": relationship_type,
304
+ "end1": {
305
+ "guid": "-1",
306
+ "typeName": row.get('source_type', 'DataSet'),
307
+ "uniqueAttributes": {
308
+ "qualifiedName": row['source_qualified_name']
309
+ }
310
+ },
311
+ "end2": {
312
+ "guid": process_guid,
313
+ "typeName": "Process"
314
+ },
315
+ "label": "inputToProcesses"
316
+ }
317
+
318
+ output_relationship = {
319
+ "guid": str(uuid.uuid4()),
320
+ "typeName": relationship_type,
321
+ "end1": {
322
+ "guid": process_guid,
323
+ "typeName": "Process"
324
+ },
325
+ "end2": {
326
+ "guid": "-1",
327
+ "typeName": row.get('target_type', 'DataSet'),
328
+ "uniqueAttributes": {
329
+ "qualifiedName": row['target_qualified_name']
330
+ }
331
+ },
332
+ "label": "outputFromProcesses"
333
+ }
292
334
 
293
335
  lineage_relationships.extend([input_relationship, output_relationship])
294
336
 
@@ -298,6 +340,126 @@ class Lineage(Endpoint):
298
340
  "referredEntities": {}
299
341
  }
300
342
 
343
+ # === CSV LINEAGE OPERATIONS ===
344
+
345
+ @decorator
346
+ def lineageCSVProcess(self, args):
347
+ """Process CSV file and create lineage relationships"""
348
+ csv_file = args.get("csv_file") or args.get("--csv-file")
349
+ if not csv_file:
350
+ raise ValueError("CSV file path is required")
351
+
352
+ # Process CSV and create lineage payload
353
+ lineage_data = self._process_csv_lineage(csv_file, args)
354
+
355
+ # Create lineage using the API
356
+ self.method = "POST"
357
+ self.endpoint = ENDPOINTS["lineage"]["create_lineage"]
358
+ self.params = get_api_version_params("datamap")
359
+ self.payload = lineage_data
360
+
361
+ # Return the payload for inspection (actual API call handled by decorator)
362
+ return lineage_data
363
+
364
+ def lineageCSVValidate(self, args):
365
+ """Validate CSV lineage file format (no API call)"""
366
+ import pandas as pd
367
+
368
+ csv_file = args.get("csv_file") or args.get("--csv-file")
369
+ if not csv_file:
370
+ return {"success": False, "error": "CSV file path is required"}
371
+
372
+ try:
373
+ # Read CSV
374
+ df = pd.read_csv(csv_file)
375
+
376
+ # Check required columns
377
+ required_columns = ['source_entity_guid', 'target_entity_guid']
378
+ missing_columns = [col for col in required_columns if col not in df.columns]
379
+
380
+ if missing_columns:
381
+ return {
382
+ "success": False,
383
+ "error": f"Missing required columns: {', '.join(missing_columns)}",
384
+ "expected_columns": required_columns
385
+ }
386
+
387
+ # Validate GUIDs format
388
+ import re
389
+ guid_pattern = re.compile(r'^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$', re.IGNORECASE)
390
+
391
+ invalid_guids = []
392
+ for idx, row in df.iterrows():
393
+ source_guid = str(row['source_entity_guid']).strip()
394
+ target_guid = str(row['target_entity_guid']).strip()
395
+
396
+ # Remove guid= prefix if present
397
+ source_guid = source_guid.replace('guid=', '').strip('"')
398
+ target_guid = target_guid.replace('guid=', '').strip('"')
399
+
400
+ if not guid_pattern.match(source_guid):
401
+ invalid_guids.append(f"Row {int(idx) + 1}: Invalid source GUID '{source_guid}'")
402
+ if not guid_pattern.match(target_guid):
403
+ invalid_guids.append(f"Row {int(idx) + 1}: Invalid target GUID '{target_guid}'")
404
+
405
+ if invalid_guids:
406
+ return {
407
+ "success": False,
408
+ "error": "Invalid GUID format(s) found",
409
+ "details": invalid_guids
410
+ }
411
+
412
+ return {
413
+ "success": True,
414
+ "rows": len(df),
415
+ "columns": list(df.columns)
416
+ }
417
+
418
+ except Exception as e:
419
+ return {"success": False, "error": str(e)}
420
+
421
+ def lineageCSVSample(self, args):
422
+ """Generate sample CSV lineage file (no API call)"""
423
+ sample_data = """source_entity_guid,target_entity_guid,relationship_type,process_name,description,confidence_score,owner,metadata
424
+ ea3412c3-7387-4bc1-9923-11f6f6f60000,2d21eba5-b08b-4571-b31d-7bf6f6f60000,Process,ETL_Customer_Transform,Transform customer data,0.95,data-engineering,"{""tool"": ""Azure Data Factory""}"
425
+ 2d21eba5-b08b-4571-b31d-7bf6f6f60000,4fae348b-e960-42f7-834c-38f6f6f60000,Process,Customer_Address_Join,Join customer with address,0.90,data-engineering,"{""tool"": ""Databricks""}"
426
+ """
427
+ output_file = args.get("--output-file") or args.get("output_file") or "lineage_sample.csv"
428
+
429
+ try:
430
+ with open(output_file, 'w', encoding='utf-8') as f:
431
+ f.write(sample_data)
432
+
433
+ return {
434
+ "success": True,
435
+ "file": output_file,
436
+ "message": f"Sample CSV file created: {output_file}"
437
+ }
438
+ except Exception as e:
439
+ return {"success": False, "error": str(e)}
440
+
441
+ def lineageCSVTemplates(self, args):
442
+ """Get available CSV lineage templates (no API call)"""
443
+ templates = {
444
+ "basic": {
445
+ "columns": ["source_entity_guid", "target_entity_guid", "relationship_type", "process_name"],
446
+ "description": "Basic lineage with source, target, and process name"
447
+ },
448
+ "detailed": {
449
+ "columns": ["source_entity_guid", "target_entity_guid", "relationship_type", "process_name", "description", "confidence_score", "owner", "metadata"],
450
+ "description": "Detailed lineage with additional metadata"
451
+ },
452
+ "qualified_names": {
453
+ "columns": ["source_qualified_name", "target_qualified_name", "source_type", "target_type", "process_name", "description"],
454
+ "description": "Lineage using qualified names instead of GUIDs"
455
+ }
456
+ }
457
+
458
+ return {
459
+ "templates": templates,
460
+ "recommended": "detailed"
461
+ }
462
+
301
463
  # === LINEAGE ANALYTICS AND REPORTING ===
302
464
 
303
465
  @decorator
@@ -93,13 +93,13 @@ class Search(Endpoint):
93
93
  self.endpoint = ENDPOINTS["discovery"]["suggest"]
94
94
  self.params = get_api_version_params("datamap")
95
95
 
96
+ # Suggest API expects keywords in search field, not keywords field
96
97
  suggest_request = {
97
- "keywords": args.get("--keywords", ""),
98
- "limit": args.get("--limit", 5),
99
- "filter": {}
98
+ "keywords": args.get("--keywords", "*"),
99
+ "limit": args.get("--limit", 5)
100
100
  }
101
101
 
102
- # Add filters if provided
102
+ # Only add filter if provided and not empty
103
103
  if args.get("--filter"):
104
104
  suggest_request["filter"] = self._parse_filter(args["--filter"])
105
105
 
@@ -107,18 +107,18 @@ class Search(Endpoint):
107
107
 
108
108
  @decorator
109
109
  def searchAutocomplete(self, args):
110
- """Get autocomplete suggestions (Official API: Autocomplete)"""
110
+ """Get search autocomplete suggestions (Official API: AutoComplete)"""
111
111
  self.method = "POST"
112
112
  self.endpoint = ENDPOINTS["discovery"]["autocomplete"]
113
113
  self.params = get_api_version_params("datamap")
114
114
 
115
+ # Autocomplete API expects keywords (text to complete)
115
116
  autocomplete_request = {
116
117
  "keywords": args.get("--keywords", ""),
117
- "limit": args.get("--limit", 10),
118
- "filter": {}
118
+ "limit": args.get("--limit", 5)
119
119
  }
120
120
 
121
- # Add filters if provided
121
+ # Only add filter if provided and not empty
122
122
  if args.get("--filter"):
123
123
  autocomplete_request["filter"] = self._parse_filter(args["--filter"])
124
124
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pvw-cli
3
- Version: 1.2.2
3
+ Version: 1.2.4
4
4
  Summary: Microsoft Purview CLI with comprehensive automation capabilities
5
5
  Author-email: AYOUB KEBAILI <keayoub@msn.com>
6
6
  Maintainer-email: AYOUB KEBAILI <keayoub@msn.com>
@@ -56,23 +56,28 @@ Requires-Dist: pytest-asyncio>=0.20.0; extra == "test"
56
56
  Requires-Dist: pytest-cov>=4.0.0; extra == "test"
57
57
  Requires-Dist: requests-mock>=1.9.0; extra == "test"
58
58
 
59
- # PURVIEW CLI v1.2.1 - Microsoft Purview Automation & Data Governance
60
-
61
- > **LATEST UPDATE (October 2025):**
62
- > - **� NEW: Bulk Term Import/Export** - Import multiple terms from CSV/JSON with dry-run support
63
- > - **🗑️ NEW: Bulk Delete Scripts** - PowerShell and Python scripts for bulk term deletion
64
- > - **📊 NEW: Multiple Output Formats** - `--output` flag supports table, json, and jsonc formats
65
- > - **🔧 NEW: PowerShell Integration** - Plain JSON output works with `ConvertFrom-Json`
66
- > - **🚀 Complete Data Product CRUD** - Full update and delete support with smart partial updates
67
- > - **🏥 Health Monitoring API** - Automated governance health checks and recommendations
68
- > - **🔄 Workflow Management** - Approval workflows and business process automation
69
- > - **🚀 Complete Microsoft Purview Unified Catalog (UC)** - Full governance domains, glossary terms, data products, OKRs, and CDEs
59
+ # PURVIEW CLI v1.2.4 - Microsoft Purview Automation & Data Governance
60
+
61
+ > **LATEST UPDATE v1.2.4 (October 2025):**
62
+ >
63
+ > - **[NEW]** Lineage CSV Import - Bulk import lineage relationships from CSV files with validation and sample generation
64
+ > - **[FIXED]** Search API Integration - Fixed `suggest` and `autocomplete` API payload format (HTTP 400 errors resolved)
65
+ > - **[ENHANCED]** Collection Display - Improved collection name detection in search results with proper fallback logic
66
+ > - **[OK]** All Search Commands - Comprehensive testing of query, browse, suggest, find-table operations
67
+ > - **[NEW]** Bulk Term Import/Export - Import multiple terms from CSV/JSON with dry-run support
68
+ > - **[NEW]** Bulk Delete Scripts - PowerShell and Python scripts for bulk term deletion
69
+ > - **[NEW]** Multiple Output Formats - `--output` flag supports table, json, and jsonc formats
70
+ > - **[NEW]** PowerShell Integration - Plain JSON output works with `ConvertFrom-Json`
71
+ > - **[OK]** Complete Data Product CRUD - Full update and delete support with smart partial updates
72
+ > - **[OK]** Health Monitoring API - Automated governance health checks and recommendations
73
+ > - **[OK]** Workflow Management - Approval workflows and business process automation
74
+ > - **[OK]** Complete Microsoft Purview Unified Catalog (UC) - Full governance domains, glossary terms, data products, OKRs, and CDEs
70
75
 
71
76
  ---
72
77
 
73
78
  ## What is PVW CLI?
74
79
 
75
- **PVW CLI v1.2.1** is a modern, full-featured command-line interface and Python library for Microsoft Purview. It enables automation and management of *all major Purview APIs* including:
80
+ **PVW CLI v1.2.4** is a modern, full-featured command-line interface and Python library for Microsoft Purview. It enables automation and management of *all major Purview APIs* including:
76
81
 
77
82
  - **Unified Catalog (UC) Management** - Complete governance domains, glossary terms, data products, OKRs, CDEs
78
83
  - **Bulk Operations** - Import/export terms from CSV/JSON, bulk delete scripts with progress tracking
@@ -89,7 +94,7 @@ The CLI is designed for data engineers, stewards, architects, and platform teams
89
94
 
90
95
  ---
91
96
 
92
- ## Getting Started
97
+ ## Getting Started
93
98
 
94
99
  Follow this short flow to get PVW CLI installed and running quickly.
95
100
 
@@ -141,8 +146,8 @@ Follow this short flow to get PVW CLI installed and running quickly.
141
146
 
142
147
  3. Authenticate
143
148
 
144
- - Run `az login` (recommended), or
145
- - Provide Service Principal credentials via environment variables.
149
+ - Run `az login` (recommended), or
150
+ - Provide Service Principal credentials via environment variables.
146
151
 
147
152
  4. Try a few commands:
148
153
 
@@ -158,13 +163,13 @@ Follow this short flow to get PVW CLI installed and running quickly.
158
163
  pvw uc --help
159
164
  ```
160
165
 
161
- For more advanced usage, see the documentation in `doc/` or the project docs: https://pvw-cli.readthedocs.io/
166
+ For more advanced usage, see the documentation in `doc/` or the project docs: <https://pvw-cli.readthedocs.io/>
162
167
 
163
168
  ---
164
169
 
165
170
  ## Overview
166
171
 
167
- **PVW CLI v1.2.1** is a modern command-line interface and Python library for Microsoft Purview, enabling:
172
+ **PVW CLI v1.2.4** is a modern command-line interface and Python library for Microsoft Purview, enabling:
168
173
 
169
174
  - Advanced data catalog search and discovery
170
175
  - Bulk import/export of entities, glossary terms, and lineage
@@ -293,6 +298,7 @@ If you are signed in to Azure in Visual Studio or VS Code, `DefaultAzureCredenti
293
298
  ---
294
299
 
295
300
  **Note:**
301
+
296
302
  - The CLI will try all supported authentication methods in order. The first one that works will be used.
297
303
  - For most automation and CI/CD scenarios, service principal authentication is recommended.
298
304
  - For local development, Azure CLI authentication is easiest.
@@ -378,11 +384,13 @@ pvw uc dataproduct list --domain-id "abc-123" --output json
378
384
  ### Migration from Old --json Flag
379
385
 
380
386
  **Old (deprecated):**
387
+
381
388
  ```bash
382
389
  pvw uc term list --domain-id "abc-123" --json
383
390
  ```
384
391
 
385
392
  **New (recommended):**
393
+
386
394
  ```bash
387
395
  pvw uc term list --domain-id "abc-123" --output json # Plain JSON for scripting
388
396
  pvw uc term list --domain-id "abc-123" --output jsonc # Colored JSON (old behavior)
@@ -397,21 +405,25 @@ Before using PVW CLI, you need to set three essential environment variables. Her
397
405
  ### 🔍 **How to Find Your Purview Values**
398
406
 
399
407
  #### **1. PURVIEW_ACCOUNT_NAME**
408
+
400
409
  - This is your Purview account name as it appears in Azure Portal
401
410
  - Example: `kaydemopurview`
402
411
 
403
- #### **2. PURVIEW_ACCOUNT_ID**
412
+ #### **2. PURVIEW_ACCOUNT_ID**
413
+
404
414
  - This is the GUID that identifies your Purview account for Unified Catalog APIs
405
- - **✅ Important: For most Purview deployments, this is your Azure Tenant ID**
415
+ - **Important: For most Purview deployments, this is your Azure Tenant ID**
406
416
 
407
417
  - **Method 1 - Get your Tenant ID (recommended):**
408
418
 
409
419
  **Bash/Command Prompt:**
420
+
410
421
  ```bash
411
422
  az account show --query tenantId -o tsv
412
423
  ```
413
424
 
414
425
  **PowerShell:**
426
+
415
427
  ```powershell
416
428
  az account show --query tenantId -o tsv
417
429
  # Or store directly in environment variable:
@@ -419,9 +431,11 @@ Before using PVW CLI, you need to set three essential environment variables. Her
419
431
  ```
420
432
 
421
433
  - **Method 2 - Azure CLI (extract from Atlas endpoint):**
434
+
422
435
  ```bash
423
436
  az purview account show --name YOUR_ACCOUNT_NAME --resource-group YOUR_RG --query endpoints.catalog -o tsv
424
437
  ```
438
+
425
439
  Extract the GUID from the URL (before `-api.purview-service.microsoft.com`)
426
440
 
427
441
  - **Method 3 - Azure Portal:**
@@ -430,12 +444,14 @@ Before using PVW CLI, you need to set three essential environment variables. Her
430
444
  3. Extract GUID from: `https://GUID-api.purview-service.microsoft.com/catalog`
431
445
 
432
446
  #### **3. PURVIEW_RESOURCE_GROUP**
447
+
433
448
  - The Azure resource group containing your Purview account
434
449
  - Example: `fabric-artifacts`
435
450
 
436
451
  ### 📋 **Setting the Variables**
437
452
 
438
453
  **Windows Command Prompt:**
454
+
439
455
  ```cmd
440
456
  set PURVIEW_ACCOUNT_NAME=your-purview-account
441
457
  set PURVIEW_ACCOUNT_ID=your-purview-account-id
@@ -443,6 +459,7 @@ set PURVIEW_RESOURCE_GROUP=your-resource-group
443
459
  ```
444
460
 
445
461
  **Windows PowerShell:**
462
+
446
463
  ```powershell
447
464
  $env:PURVIEW_ACCOUNT_NAME="your-purview-account"
448
465
  $env:PURVIEW_ACCOUNT_ID="your-purview-account-id"
@@ -450,6 +467,7 @@ $env:PURVIEW_RESOURCE_GROUP="your-resource-group"
450
467
  ```
451
468
 
452
469
  **Linux/macOS:**
470
+
453
471
  ```bash
454
472
  export PURVIEW_ACCOUNT_NAME=your-purview-account
455
473
  export PURVIEW_ACCOUNT_ID=your-purview-account-id
@@ -457,6 +475,7 @@ export PURVIEW_RESOURCE_GROUP=your-resource-group
457
475
  ```
458
476
 
459
477
  **Permanent (Windows Command Prompt):**
478
+
460
479
  ```cmd
461
480
  setx PURVIEW_ACCOUNT_NAME "your-purview-account"
462
481
  setx PURVIEW_ACCOUNT_ID "your-purview-account-id"
@@ -464,17 +483,19 @@ setx PURVIEW_RESOURCE_GROUP "your-resource-group"
464
483
  ```
465
484
 
466
485
  **Permanent (Windows PowerShell):**
486
+
467
487
  ```powershell
468
488
  [Environment]::SetEnvironmentVariable("PURVIEW_ACCOUNT_NAME", "your-purview-account", "User")
469
489
  [Environment]::SetEnvironmentVariable("PURVIEW_ACCOUNT_ID", "your-purview-account-id", "User")
470
490
  [Environment]::SetEnvironmentVariable("PURVIEW_RESOURCE_GROUP", "your-resource-group", "User")
471
491
  ```
472
492
 
473
- ### 🔧 **Debug Environment Issues**
493
+ ### **Debug Environment Issues**
474
494
 
475
495
  If you experience issues with environment variables between different terminals, use these debug commands:
476
496
 
477
497
  **Command Prompt/Bash:**
498
+
478
499
  ```bash
479
500
  # Run this to check your current environment
480
501
  python -c "
@@ -486,6 +507,7 @@ print('PURVIEW_RESOURCE_GROUP:', os.getenv('PURVIEW_RESOURCE_GROUP'))
486
507
  ```
487
508
 
488
509
  **PowerShell:**
510
+
489
511
  ```powershell
490
512
  # Check environment variables in PowerShell
491
513
  python -c "
@@ -511,9 +533,15 @@ The PVW CLI provides advanced search using the latest Microsoft Purview Discover
511
533
  - Use autocomplete and suggestion endpoints
512
534
  - Perform faceted, time-based, and entity-type-specific queries
513
535
 
536
+ **v1.2.4 Improvements:**
537
+
538
+ - Fixed `suggest` and `autocomplete` API payload format (removed empty filter causing HTTP 400 errors)
539
+ - Enhanced collection display with robust type checking and fallback logic
540
+ - All search commands validated and working correctly (query, browse, suggest, find-table)
541
+
514
542
  ### CLI Usage Examples
515
543
 
516
- #### 🎯 **Multiple Output Formats**
544
+ #### **Multiple Output Formats**
517
545
 
518
546
  ```bash
519
547
  # 1. Table Format (Default) - Quick overview
@@ -533,7 +561,7 @@ pvw search query --keywords="customer" --limit=5 --show-ids
533
561
  # → Table format + entity GUIDs for copy/paste into update commands
534
562
  ```
535
563
 
536
- #### 🔍 **Search Operations**
564
+ #### **Search Operations**
537
565
 
538
566
  ```bash
539
567
  # Basic search for assets with keyword 'customer'
@@ -551,12 +579,12 @@ pvw search autocomplete --keywords="ord" --limit=3
551
579
  # Get search suggestions (fuzzy matching)
552
580
  pvw search suggest --keywords="prod" --limit=2
553
581
 
554
- **⚠️ IMPORTANT - Command Line Quoting:**
582
+ **IMPORTANT - Command Line Quoting:**
555
583
  ```cmd
556
- # CORRECT - Use quotes around keywords
584
+ # [OK] CORRECT - Use quotes around keywords
557
585
  pvw search query --keywords="customer" --limit=5
558
586
 
559
- # CORRECT - For wildcard searches, use quotes
587
+ # [OK] CORRECT - For wildcard searches, use quotes
560
588
  pvw search query --keywords="*" --limit=5
561
589
 
562
590
  # ❌ WRONG - Don't use unquoted * (shell expands to file names)
@@ -578,7 +606,7 @@ pvw search query --keywords="audit" --createdAfter="2024-01-01" --limit=1
578
606
  pvw search query --keywords="finance" --entityTypes="Files,Tables" --limit=2
579
607
  ```
580
608
 
581
- #### 💡 **Usage Scenarios**
609
+ #### **Usage Scenarios**
582
610
 
583
611
  - **Daily browsing**: Use default table format for quick scans
584
612
  - **Understanding assets**: Use `--detailed` for rich information panels
@@ -621,7 +649,7 @@ See [`doc/commands/unified-catalog.md`](doc/commands/unified-catalog.md) for com
621
649
 
622
650
  ### Quick UC Examples
623
651
 
624
- #### 🏛️ **Governance Domains Management**
652
+ #### **Governance Domains Management**
625
653
 
626
654
  ```bash
627
655
  # List all governance domains
@@ -637,7 +665,7 @@ pvw uc domain get --domain-id "abc-123-def-456"
637
665
  pvw uc domain update --domain-id "abc-123" --description "Updated financial governance"
638
666
  ```
639
667
 
640
- #### 📖 **Glossary Terms in UC**
668
+ #### **Glossary Terms in UC**
641
669
 
642
670
  ```bash
643
671
  # List all terms in a domain
@@ -678,14 +706,16 @@ pvw uc term import-json --json-file "samples/json/term/uc_terms_bulk_example.jso
678
706
  ```
679
707
 
680
708
  **Bulk Import Features:**
681
- - ✅ Import from CSV or JSON files
682
- - Dry-run mode to preview before importing
683
- - Support for multiple owners (Entra ID Object IDs), acronyms, and resources
684
- - Progress tracking with Rich console output
685
- - Detailed error messages and summary reports
686
- - Sequential POST requests (no native bulk endpoint available)
709
+
710
+ - [OK] Import from CSV or JSON files
711
+ - [OK] Dry-run mode to preview before importing
712
+ - [OK] Support for multiple owners (Entra ID Object IDs), acronyms, and resources
713
+ - [OK] Progress tracking with Rich console output
714
+ - [OK] Detailed error messages and summary reports
715
+ - [OK] Sequential POST requests (no native bulk endpoint available)
687
716
 
688
717
  **CSV Format Example:**
718
+
689
719
  ```csv
690
720
  name,description,status,acronym,owner_id,resource_name,resource_url
691
721
  Customer Acquisition Cost,Cost to acquire new customer,Draft,CAC,<guid>,Metrics Guide,https://docs.example.com
@@ -693,6 +723,7 @@ Monthly Recurring Revenue,Predictable monthly revenue,Draft,MRR,<guid>,Finance D
693
723
  ```
694
724
 
695
725
  **JSON Format Example:**
726
+
696
727
  ```json
697
728
  {
698
729
  "terms": [
@@ -710,9 +741,10 @@ Monthly Recurring Revenue,Predictable monthly revenue,Draft,MRR,<guid>,Finance D
710
741
  ```
711
742
 
712
743
  **Important Notes:**
744
+
713
745
  - ⚠️ **Owner IDs must be Entra ID Object IDs (GUIDs)**, not email addresses
714
746
  - ⚠️ **Terms cannot be "Published" in unpublished domains** - use "Draft" status
715
- - Sample files available: `samples/csv/uc_terms_bulk_example.csv`, `samples/json/term/uc_terms_bulk_example.json`
747
+ - [OK] Sample files available: `samples/csv/uc_terms_bulk_example.csv`, `samples/json/term/uc_terms_bulk_example.json`
716
748
  - 📖 Complete documentation: [`doc/commands/unified-catalog/term-bulk-import.md`](doc/commands/unified-catalog/term-bulk-import.md)
717
749
 
718
750
  **🗑️ Bulk Delete (NEW)**
@@ -736,14 +768,15 @@ python scripts/delete_all_uc_terms_v2.py --domain-id "abc-123" --force
736
768
  ```
737
769
 
738
770
  **Bulk Delete Features:**
739
- - ✅ Interactive confirmation prompts (type "DELETE" to confirm)
740
- - ✅ Beautiful progress display with colors
741
- - ✅ Success/failure tracking per term
742
- - ✅ Detailed summary reports
743
- - ✅ Rate limiting (200ms delay between deletes)
744
- - ✅ Graceful error handling and Ctrl+C support
745
771
 
746
- #### 📦 **Data Products Management**
772
+ - [OK] Interactive confirmation prompts (type "DELETE" to confirm)
773
+ - [OK] Beautiful progress display with colors
774
+ - [OK] Success/failure tracking per term
775
+ - [OK] Detailed summary reports
776
+ - [OK] Rate limiting (200ms delay between deletes)
777
+ - [OK] Graceful error handling and Ctrl+C support
778
+
779
+ #### **Data Products Management**
747
780
 
748
781
  ```bash
749
782
  # List all data products in a domain
@@ -781,7 +814,7 @@ pvw uc dataproduct delete --product-id "prod-789"
781
814
  pvw uc dataproduct delete --product-id "prod-789" --yes
782
815
  ```
783
816
 
784
- #### 🎯 **Objectives & Key Results (OKRs)**
817
+ #### **Objectives & Key Results (OKRs)**
785
818
 
786
819
  ```bash
787
820
  # List objectives for a domain
@@ -802,7 +835,7 @@ pvw uc objective update \
802
835
  --status "in-progress"
803
836
  ```
804
837
 
805
- #### 🔑 **Critical Data Elements (CDEs)**
838
+ #### **Critical Data Elements (CDEs)**
806
839
 
807
840
  ```bash
808
841
  # List critical data elements
@@ -823,7 +856,7 @@ pvw uc cde link \
823
856
  --asset-id "ea3412c3-7387-4bc1-9923-11f6f6f60000"
824
857
  ```
825
858
 
826
- #### 🏥 **Health Monitoring (NEW)**
859
+ #### **Health Monitoring (NEW)**
827
860
 
828
861
  Monitor governance health and get automated recommendations to improve your data governance posture.
829
862
 
@@ -856,6 +889,7 @@ pvw uc health query --json
856
889
  ```
857
890
 
858
891
  **Health Finding Types:**
892
+
859
893
  - Missing glossary terms on data products (High)
860
894
  - Data products without OKRs (Medium)
861
895
  - Missing data quality scores (Medium)
@@ -863,7 +897,7 @@ pvw uc health query --json
863
897
  - Description quality issues (Medium)
864
898
  - Business domains without critical data entities (Medium)
865
899
 
866
- #### 🔄 **Workflow Management (NEW)**
900
+ #### **Workflow Management (NEW)**
867
901
 
868
902
  Manage approval workflows and business process automation in Purview.
869
903
 
@@ -897,12 +931,13 @@ pvw workflow list --json
897
931
  ```
898
932
 
899
933
  **Workflow Use Cases:**
934
+
900
935
  - Data access request approvals
901
936
  - Glossary term certification workflows
902
937
  - Data product publishing approvals
903
938
  - Classification review processes
904
939
 
905
- #### 🔄 **Integrated Workflow Example**
940
+ #### **Integrated Workflow Example**
906
941
 
907
942
  ```bash
908
943
  # 1. Discover assets to govern
@@ -927,7 +962,7 @@ pvw uc objective create --definition "Ensure 100% PII classification compliance"
927
962
 
928
963
  PVW CLI provides comprehensive entity management capabilities for updating Purview assets like descriptions, classifications, and custom attributes.
929
964
 
930
- ### 🔄 **Entity Update Examples**
965
+ ### **Entity Update Examples**
931
966
 
932
967
  #### **Update Asset Descriptions**
933
968
 
@@ -974,7 +1009,7 @@ pvw entity add-classification \
974
1009
  --classification "MICROSOFT.PERSONAL.EMAIL"
975
1010
  ```
976
1011
 
977
- ### 🔍 **Discovery to Update Workflow**
1012
+ ### **Discovery to Update Workflow**
978
1013
 
979
1014
  ```bash
980
1015
  # 1. Find assets that need updates
@@ -995,6 +1030,90 @@ pvw search query --keywords="FOUND_GUID" --detailed
995
1030
 
996
1031
  ---
997
1032
 
1033
+ ## Lineage CSV Import & Management
1034
+
1035
+ PVW CLI provides powerful lineage management capabilities including CSV-based bulk import for automating data lineage creation.
1036
+
1037
+ ### **Lineage CSV Import**
1038
+
1039
+ Import lineage relationships from CSV files to automate the creation of data flow documentation in Microsoft Purview.
1040
+
1041
+ #### **CSV Format**
1042
+
1043
+ The CSV file must contain the following columns:
1044
+
1045
+ **Required columns:**
1046
+
1047
+ - `source_entity_guid` - GUID of the source entity
1048
+ - `target_entity_guid` - GUID of the target entity
1049
+
1050
+ **Optional columns:**
1051
+
1052
+ - `relationship_type` - Type of relationship (default: "Process")
1053
+ - `process_name` - Name of the transformation process
1054
+ - `description` - Description of the transformation
1055
+ - `confidence_score` - Confidence score (0-1)
1056
+ - `owner` - Process owner
1057
+ - `metadata` - Additional JSON metadata
1058
+
1059
+ **Example CSV:**
1060
+
1061
+ ```csv
1062
+ source_entity_guid,target_entity_guid,relationship_type,process_name,description,confidence_score,owner,metadata
1063
+ dcfc99ed-c74d-49aa-bd0b-72f6f6f60000,1db9c650-acfb-4914-8bc5-1cf6f6f60000,Process,Transform_Product_Data,Transform product data for analytics,0.95,data-engineering,"{""tool"": ""Azure Data Factory""}"
1064
+ ```
1065
+
1066
+ #### **Lineage Commands**
1067
+
1068
+ ```bash
1069
+ # Validate CSV format before import (no API calls)
1070
+ pvw lineage validate lineage_data.csv
1071
+
1072
+ # Import lineage relationships from CSV
1073
+ pvw lineage import lineage_data.csv
1074
+
1075
+ # Generate sample CSV file with examples
1076
+ pvw lineage sample output.csv --num-samples 10 --template detailed
1077
+
1078
+ # View available CSV templates
1079
+ pvw lineage templates
1080
+ ```
1081
+
1082
+ #### **Available Templates**
1083
+
1084
+ - **`basic`** - Minimal columns (source, target, process name)
1085
+ - **`detailed`** - All columns including metadata and confidence scores
1086
+ - **`qualified_names`** - Use qualified names instead of GUIDs
1087
+
1088
+ #### **Workflow Example**
1089
+
1090
+ ```bash
1091
+ # 1. Find entity GUIDs using search
1092
+ pvw search find-table --name "Product" --schema "dbo" --id-only
1093
+
1094
+ # 2. Create CSV file with lineage relationships
1095
+ # (use the GUIDs from step 1)
1096
+
1097
+ # 3. Validate CSV format
1098
+ pvw lineage validate my_lineage.csv
1099
+ # Output: SUCCESS: Lineage validation passed (5 rows, 8 columns)
1100
+
1101
+ # 4. Import to Purview
1102
+ pvw lineage import my_lineage.csv
1103
+ # Output: SUCCESS: Lineage import completed successfully
1104
+ ```
1105
+
1106
+ #### **Advanced Features**
1107
+
1108
+ - **GUID Validation**: Automatic validation of GUID format with helpful error messages
1109
+ - **Process Entity Creation**: Creates intermediate "Process" entities to link source→target relationships
1110
+ - **Metadata Support**: Add custom JSON metadata to each lineage relationship
1111
+ - **Dry-Run Validation**: Validate CSV format locally before making API calls
1112
+
1113
+ **For detailed documentation, see:** [`doc/guides/lineage-csv-import.md`](doc/guides/lineage-csv-import.md)
1114
+
1115
+ ---
1116
+
998
1117
  ## Data Product Management (Legacy)
999
1118
 
1000
1119
  PVW CLI also includes the original `data-product` command group for backward compatibility with traditional data product lifecycle management.
@@ -1024,15 +1143,18 @@ pvw data-product show-lineage --qualified-name="product.test.1"
1024
1143
  ## Core Features
1025
1144
 
1026
1145
  - **Unified Catalog (UC)**: Complete modern data governance (NEW)
1146
+
1027
1147
  ```bash
1028
1148
  # Manage governance domains, terms, data products, OKRs, CDEs
1029
1149
  pvw uc domain list
1030
1150
  pvw uc term create --name "Customer" --domain-id "abc-123"
1031
1151
  pvw uc objective create --definition "Improve quality" --domain-id "abc-123"
1032
1152
  ```
1153
+
1033
1154
  - **Discovery Query/Search**: Flexible, advanced search for all catalog assets
1034
1155
  - **Entity Management**: Bulk import/export, update, and validation
1035
1156
  - **Glossary Management**: Import/export terms, assign terms in bulk
1157
+
1036
1158
  ```bash
1037
1159
  # List all terms in a glossary
1038
1160
  pvw glossary list-terms --glossary-guid "your-glossary-guid"
@@ -1040,7 +1162,20 @@ pvw data-product show-lineage --qualified-name="product.test.1"
1040
1162
  # Create and manage glossary terms
1041
1163
  pvw glossary create-term --payload-file term.json
1042
1164
  ```
1043
- - **Lineage Operations**: Lineage discovery, CSV-based bulk lineage
1165
+
1166
+ - **Lineage Operations**: Lineage discovery, CSV-based bulk lineage import/export
1167
+
1168
+ ```bash
1169
+ # Import lineage relationships from CSV
1170
+ pvw lineage import lineage_data.csv
1171
+
1172
+ # Validate CSV format before import
1173
+ pvw lineage validate lineage_data.csv
1174
+
1175
+ # Generate sample CSV file
1176
+ pvw lineage sample output.csv --num-samples 10
1177
+ ```
1178
+
1044
1179
  - **Monitoring & Analytics**: Real-time dashboards, metrics, and reporting
1045
1180
  - **Plugin System**: Extensible with custom plugins
1046
1181
 
@@ -1052,14 +1187,14 @@ PVW CLI provides comprehensive automation for all major Microsoft Purview APIs,
1052
1187
 
1053
1188
  ### Supported API Groups
1054
1189
 
1055
- - **Unified Catalog**: Complete governance domains, glossary terms, data products, OKRs, CDEs management
1056
- - **Health Monitoring**: Automated governance health checks and recommendations NEW
1057
- - **Workflows**: Approval workflows and business process automation NEW
1058
- - **Data Map**: Full entity and lineage management
1059
- - **Discovery**: Advanced search, browse, and query capabilities
1060
- - **Collections**: Collection and account management
1061
- - **Management**: Administrative operations
1062
- - **Scan**: Data source scanning and configuration
1190
+ - **Unified Catalog**: Complete governance domains, glossary terms, data products, OKRs, CDEs management [OK]
1191
+ - **Health Monitoring**: Automated governance health checks and recommendations [OK] NEW
1192
+ - **Workflows**: Approval workflows and business process automation [OK] NEW
1193
+ - **Data Map**: Full entity and lineage management [OK]
1194
+ - **Discovery**: Advanced search, browse, and query capabilities [OK]
1195
+ - **Collections**: Collection and account management [OK]
1196
+ - **Management**: Administrative operations [OK]
1197
+ - **Scan**: Data source scanning and configuration [OK]
1063
1198
 
1064
1199
  ### API Version Support
1065
1200
 
@@ -1071,6 +1206,7 @@ PVW CLI provides comprehensive automation for all major Microsoft Purview APIs,
1071
1206
  - Scan: **2018-12-01-preview**
1072
1207
 
1073
1208
  For the latest API documentation and updates, see:
1209
+
1074
1210
  - [Microsoft Purview REST API reference](https://learn.microsoft.com/en-us/rest/api/purview/)
1075
1211
  - [Atlas 2.2 API documentation](https://learn.microsoft.com/en-us/purview/data-gov-api-atlas-2-2)
1076
1212
  - [Azure Updates](https://azure.microsoft.com/updates/) for new releases
@@ -1086,9 +1222,18 @@ PVW CLI includes comprehensive sample files and scripts for bulk operations:
1086
1222
  ### Bulk Import Samples
1087
1223
 
1088
1224
  - **CSV Samples:** `samples/csv/uc_terms_bulk_example.csv` (8 sample terms)
1089
- - **JSON Samples:**
1225
+ - **JSON Samples:**
1090
1226
  - `samples/json/term/uc_terms_bulk_example.json` (8 data management terms)
1091
1227
  - `samples/json/term/uc_terms_sample.json` (8 business terms)
1228
+ - **Lineage CSV Samples:** `samples/csv/lineage_example.csv` - Multiple lineage relationships with metadata
1229
+
1230
+ ### Lineage Documentation
1231
+
1232
+ - **Comprehensive Guide:** `doc/guides/lineage-csv-import.md` - Complete lineage CSV import documentation
1233
+ - CSV format specification with required/optional columns
1234
+ - Command examples for validate, import, sample, templates
1235
+ - Workflow recommendations and troubleshooting
1236
+ - Advanced scenarios with metadata and multiple transformations
1092
1237
 
1093
1238
  ### Bulk Delete Scripts
1094
1239
 
@@ -1129,58 +1274,70 @@ PVW CLI includes comprehensive sample files and scripts for bulk operations:
1129
1274
 
1130
1275
  ## Recent Updates (October 2025)
1131
1276
 
1132
- ### Bulk Term Import/Export
1277
+ ### Bulk Term Import/Export
1278
+
1133
1279
  - Import multiple terms from CSV or JSON files
1134
1280
  - Dry-run mode for validation before import
1135
1281
  - Support for owners (Entra ID GUIDs), acronyms, resources
1136
1282
  - Progress tracking and detailed error reporting
1137
1283
  - 100% success rate in testing (8/8 terms)
1138
1284
 
1139
- ### PowerShell & Scripting Integration
1285
+ ### PowerShell & Scripting Integration
1286
+
1140
1287
  - New `--output` parameter with table/json/jsonc formats
1141
1288
  - Plain JSON works with PowerShell's `ConvertFrom-Json`
1142
1289
  - Compatible with jq, Python json module, and other tools
1143
1290
  - Migration from deprecated `--json` flag
1144
1291
 
1145
- ### Bulk Delete Scripts
1292
+ ### Bulk Delete Scripts
1293
+
1146
1294
  - PowerShell script with interactive confirmation ("DELETE" to confirm)
1147
1295
  - Python script with Rich progress bars
1148
1296
  - Beautiful UI with colored output
1149
1297
  - Success/failure tracking per term
1150
1298
  - Rate limiting (200ms delay)
1151
1299
 
1152
- ### Critical Fixes
1300
+ ### Critical Fixes (v1.2.4)
1301
+
1302
+ - **Search API Suggest/Autocomplete:** Fixed HTTP 400 errors by removing empty filter objects from payload
1303
+ - **Collection Display:** Enhanced collection name detection with proper fallback logic (isinstance checks)
1153
1304
  - **Owner ID Format:** Must use Entra ID Object IDs (GUIDs), not email addresses
1154
1305
  - **Domain Status:** Terms cannot be "Published" in unpublished domains - use "Draft"
1155
1306
  - **Error Validation:** Enhanced error handling shows actual API responses
1307
+ - **Windows Console Compatibility:** All emoji removed for CP-1252 encoding support
1156
1308
 
1157
1309
  ---
1158
1310
 
1159
1311
  ## Key Features Summary
1160
1312
 
1161
- ### 🚀 **Unified Catalog (UC) - Complete Management**
1313
+ ### **Unified Catalog (UC) - Complete Management**
1314
+
1162
1315
  - Governance domains, glossary terms, data products
1163
1316
  - Objectives & Key Results (OKRs), Critical Data Elements (CDEs)
1164
1317
  - Health monitoring and workflow automation
1165
1318
  - Full CRUD operations with smart partial updates
1166
1319
 
1167
- ### 📦 **Bulk Operations**
1320
+ ### **Bulk Operations**
1321
+
1168
1322
  - CSV/JSON import with dry-run validation
1169
1323
  - PowerShell and Python bulk delete scripts
1170
1324
  - Progress tracking and error handling
1171
1325
  - Sample files and templates included
1172
1326
 
1173
- ### 📊 **Multiple Output Formats**
1327
+ ### **Multiple Output Formats**
1328
+
1174
1329
  - Table format for human viewing (default)
1175
1330
  - Plain JSON for PowerShell/bash scripting
1176
1331
  - Colored JSON for visual inspection
1177
1332
 
1178
- ### 🔧 **Automation & Integration**
1333
+ ### **Automation & Integration**
1334
+
1179
1335
  - Azure CLI, Service Principal, Managed Identity auth
1180
1336
  - Works in local development, CI/CD, and production
1181
1337
  - Compatible with PowerShell, bash, Python, jq
1182
1338
 
1183
- ### 📚 **Comprehensive Documentation**
1339
+ ### **Comprehensive Documentation**
1340
+
1184
1341
  - Complete API coverage documentation
1185
1342
  - Jupyter notebook examples
1186
1343
  - Troubleshooting guides
@@ -1203,6 +1360,13 @@ See [LICENSE](LICENSE) file for details.
1203
1360
 
1204
1361
  ---
1205
1362
 
1206
- **PVW CLI v1.2.1 empowers data engineers, stewards, and architects to automate, scale, and enhance their Microsoft Purview experience with powerful command-line and programmatic capabilities.**
1363
+ **PVW CLI v1.2.4 empowers data engineers, stewards, and architects to automate, scale, and enhance their Microsoft Purview experience with powerful command-line and programmatic capabilities.**
1364
+
1365
+ **Latest in v1.2.4:**
1207
1366
 
1208
- **Latest Features:** Bulk term import/export, PowerShell integration, multiple output formats, and comprehensive bulk delete scripts with beautiful progress tracking.
1367
+ - Fixed Search API suggest/autocomplete (HTTP 400 errors resolved)
1368
+ - Enhanced collection display with robust fallback logic
1369
+ - Comprehensive search command validation
1370
+ - Bulk term import/export with dry-run support
1371
+ - PowerShell integration with plain JSON output
1372
+ - Multiple output formats and beautiful progress tracking
@@ -1,4 +1,4 @@
1
- purviewcli/__init__.py,sha256=Il2mms3-8s3w6aOlY9gbkhSAb3HwmkqDvOzH1jgcPH8,417
1
+ purviewcli/__init__.py,sha256=lSZ3EF_IssYkUVjlovhrmDVuTyx6CcOQDc2utNknygM,413
2
2
  purviewcli/__main__.py,sha256=n_PFo1PjW8L1OKCNLsW0vlVSo8tzac_saEYYLTu93iQ,372
3
3
  purviewcli/cli/__init__.py,sha256=UGMctZaXXsV2l2ycnmhTgyksH81_JBQjAPq3oRF2Dqk,56
4
4
  purviewcli/cli/account.py,sha256=Z_bwhKriMQpoBicOORM64wpQ1MJ94QG7jGKiaG-D_r8,7092
@@ -9,12 +9,12 @@ purviewcli/cli/entity.py,sha256=CMUnzYyRbHUQFGa_XLo2Yq189WcomZ16OyiSDzMvN4A,9484
9
9
  purviewcli/cli/glossary.py,sha256=6oTU7qPkUFkty4TPBPc8c1w2tbn1HicQ5qSxrP5vHFE,25696
10
10
  purviewcli/cli/health.py,sha256=_vuJgoLiihkKeU_L6bTzrCY2o9_gWqQS6gMXJ4EZyCA,10549
11
11
  purviewcli/cli/insight.py,sha256=dJYgTC9jQz62YnpDGUGj4ClXcdDsrGDr4sEvZbq90yE,3853
12
- purviewcli/cli/lineage.py,sha256=PWruMN_ttp-I-rv0adeaql5HXNFGiaVpr_pFKuj4ixU,21360
12
+ purviewcli/cli/lineage.py,sha256=0im1sOlT0vtDkpdP68OLj_jggmzSDPeHsGMmlenawxk,21508
13
13
  purviewcli/cli/management.py,sha256=ArSN7ADWMKUJ-fVYjPiuab4g666GQUmxU2WZov3JxzI,7886
14
14
  purviewcli/cli/policystore.py,sha256=Xj3Yx6kNt9W8v577x2iacqSlPatR6AuFfMBpjtHTj1E,4439
15
15
  purviewcli/cli/relationship.py,sha256=Ky4klI-clKh6sRK7bsI7SwgtVrpo1ljegVyrbqjkeOY,2682
16
16
  purviewcli/cli/scan.py,sha256=91iKDH8iVNJKndJAisrKx3J4HRoPH2qfmxguLZH3xHY,13807
17
- purviewcli/cli/search.py,sha256=SUuNwWXn33REAkXhS0zk1roJtkVtY470UhjI5YPVPM8,22348
17
+ purviewcli/cli/search.py,sha256=QNAKiFSi8oSEwzh-ksR4vhNAZ1z0dje1icdg36xRMvk,22667
18
18
  purviewcli/cli/share.py,sha256=QRZhHM59RxdYqXOjSYLfVRZmjwMg4Y-bWxMSQVTQiIE,20197
19
19
  purviewcli/cli/types.py,sha256=zo_8rAqDQ1vqi5y-dBh_sVY6i16UaJLLx_vBJBfZrrw,23729
20
20
  purviewcli/cli/unified_catalog.py,sha256=ZQn5GsHsfXCrjzTPnfNA6gfGBOD5AH2m7uauGZt-oZs,74753
@@ -27,12 +27,12 @@ purviewcli/client/_entity.py,sha256=oGvnHpI8bFX7VOyH_aqgoGU37hnMqAjsXPEEBtk29vQ,
27
27
  purviewcli/client/_glossary.py,sha256=7kB3RXVOCCR1RGlaALmr_BwN6S76-xCoyVqD5ZMzt-k,20985
28
28
  purviewcli/client/_health.py,sha256=bKX2PChw2OB2kD_ZEfWlDxc093qQX3ai31YCQQ2VaKg,5921
29
29
  purviewcli/client/_insight.py,sha256=2KX6dVAkyFFMLuQ02Ko2J7WhARKlCLhSgtFkjFJxZ7c,16031
30
- purviewcli/client/_lineage.py,sha256=z-yckIduq4Ed9EXTWe-2hqBvl37t5yl87wzVPD_c3y0,14633
30
+ purviewcli/client/_lineage.py,sha256=GsxeAnndtpxsV1X4mgY0461t27txHEaHOMdFEOS34L4,21864
31
31
  purviewcli/client/_management.py,sha256=2_ZXRSeEzGuHv1muUbn8mQb07enYYuHPI3NskIHIVbk,19549
32
32
  purviewcli/client/_policystore.py,sha256=wx9Yw6wcvj236ZmmitUKxW5u4YAtfJqAFNuxMpa7HIU,18078
33
33
  purviewcli/client/_relationship.py,sha256=KJZRltrzpTw7cfKjlZH2MuoTPS7eHxxp3cqU2etDSEA,9997
34
34
  purviewcli/client/_scan.py,sha256=2atEBD-kKWtFuBSWh2P0cwp42gfg7qgwWq-072QZMs4,15154
35
- purviewcli/client/_search.py,sha256=vUDgjZtnNkHaCqsCXPp1Drq9Kknrkid17RNSXZhi1yw,11890
35
+ purviewcli/client/_search.py,sha256=9QfRE7FUukhpMQ_Xc9NziG6aKFMlPt4_OVaI0QinGa8,12019
36
36
  purviewcli/client/_share.py,sha256=vKENIhePuzi3WQazNfv5U9y-6yxRk222zrFA-SGh1pc,10494
37
37
  purviewcli/client/_types.py,sha256=ONa3wh1F02QOVy51UGq54121TkqRcWczdXIvNqPIFU0,15454
38
38
  purviewcli/client/_unified_catalog.py,sha256=WDpl68NJXfMJ5OIlING0wrfXwbOLwbnGRAFL9WPZnCE,40017
@@ -53,8 +53,8 @@ purviewcli/client/settings.py,sha256=nYdnYurTZsgv9vcgljnzVxLPtYVl9q6IplqOzi1aRvI
53
53
  purviewcli/client/sync_client.py,sha256=gwCqesJTNaXn1Q-j57O95R9mn3fIOhdP4sc8jBaBcYw,9493
54
54
  purviewcli/plugins/__init__.py,sha256=rpt3OhFt_wSE_o8Ga8AXvw1pqkdBxLmjrhYtE_-LuJo,29
55
55
  purviewcli/plugins/plugin_system.py,sha256=C-_dL4FUj90o1JS7Saxkpov6fz0GIF5PFhZTYwqBkWE,26774
56
- pvw_cli-1.2.2.dist-info/METADATA,sha256=PUHNR04aW61FnLpz_tR1n_H_55nUwGVZgpqU8t87sBw,39121
57
- pvw_cli-1.2.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
58
- pvw_cli-1.2.2.dist-info/entry_points.txt,sha256=VI6AAbc6sWahOCX7sn_lhJIr9OiJM0pHF7rmw1YVGlE,82
59
- pvw_cli-1.2.2.dist-info/top_level.txt,sha256=LrADzPoKwF1xY0pGKpWauyOVruHCIWKCkT7cwIl6IuI,11
60
- pvw_cli-1.2.2.dist-info/RECORD,,
56
+ pvw_cli-1.2.4.dist-info/METADATA,sha256=hi7EZ8xiZ8tbkVj85fFnvqCM8qF-7O6BR8iQiAdYa0w,43762
57
+ pvw_cli-1.2.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
58
+ pvw_cli-1.2.4.dist-info/entry_points.txt,sha256=VI6AAbc6sWahOCX7sn_lhJIr9OiJM0pHF7rmw1YVGlE,82
59
+ pvw_cli-1.2.4.dist-info/top_level.txt,sha256=LrADzPoKwF1xY0pGKpWauyOVruHCIWKCkT7cwIl6IuI,11
60
+ pvw_cli-1.2.4.dist-info/RECORD,,