pvw-cli 1.3.3__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.
- purviewcli/__init__.py +27 -0
- purviewcli/__main__.py +15 -0
- purviewcli/cli/__init__.py +5 -0
- purviewcli/cli/account.py +199 -0
- purviewcli/cli/cli.py +170 -0
- purviewcli/cli/collections.py +502 -0
- purviewcli/cli/domain.py +361 -0
- purviewcli/cli/entity.py +2436 -0
- purviewcli/cli/glossary.py +533 -0
- purviewcli/cli/health.py +250 -0
- purviewcli/cli/insight.py +113 -0
- purviewcli/cli/lineage.py +1103 -0
- purviewcli/cli/management.py +141 -0
- purviewcli/cli/policystore.py +103 -0
- purviewcli/cli/relationship.py +75 -0
- purviewcli/cli/scan.py +357 -0
- purviewcli/cli/search.py +527 -0
- purviewcli/cli/share.py +478 -0
- purviewcli/cli/types.py +831 -0
- purviewcli/cli/unified_catalog.py +3796 -0
- purviewcli/cli/workflow.py +402 -0
- purviewcli/client/__init__.py +21 -0
- purviewcli/client/_account.py +1877 -0
- purviewcli/client/_collections.py +1761 -0
- purviewcli/client/_domain.py +414 -0
- purviewcli/client/_entity.py +3545 -0
- purviewcli/client/_glossary.py +3233 -0
- purviewcli/client/_health.py +501 -0
- purviewcli/client/_insight.py +2873 -0
- purviewcli/client/_lineage.py +2138 -0
- purviewcli/client/_management.py +2202 -0
- purviewcli/client/_policystore.py +2915 -0
- purviewcli/client/_relationship.py +1351 -0
- purviewcli/client/_scan.py +2607 -0
- purviewcli/client/_search.py +1472 -0
- purviewcli/client/_share.py +272 -0
- purviewcli/client/_types.py +2708 -0
- purviewcli/client/_unified_catalog.py +5112 -0
- purviewcli/client/_workflow.py +2734 -0
- purviewcli/client/api_client.py +1295 -0
- purviewcli/client/business_rules.py +675 -0
- purviewcli/client/config.py +231 -0
- purviewcli/client/data_quality.py +433 -0
- purviewcli/client/endpoint.py +123 -0
- purviewcli/client/endpoints.py +554 -0
- purviewcli/client/exceptions.py +38 -0
- purviewcli/client/lineage_visualization.py +797 -0
- purviewcli/client/monitoring_dashboard.py +712 -0
- purviewcli/client/rate_limiter.py +30 -0
- purviewcli/client/retry_handler.py +125 -0
- purviewcli/client/scanning_operations.py +523 -0
- purviewcli/client/settings.py +1 -0
- purviewcli/client/sync_client.py +250 -0
- purviewcli/plugins/__init__.py +1 -0
- purviewcli/plugins/plugin_system.py +709 -0
- pvw_cli-1.3.3.dist-info/METADATA +1618 -0
- pvw_cli-1.3.3.dist-info/RECORD +60 -0
- pvw_cli-1.3.3.dist-info/WHEEL +5 -0
- pvw_cli-1.3.3.dist-info/entry_points.txt +3 -0
- pvw_cli-1.3.3.dist-info/top_level.txt +1 -0
purviewcli/__init__.py
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
__version__ = "1.3.3"
|
|
2
|
+
|
|
3
|
+
# Import main client modules
|
|
4
|
+
from .client import *
|
|
5
|
+
from .cli import *
|
|
6
|
+
|
|
7
|
+
__all__ = [
|
|
8
|
+
"__version__",
|
|
9
|
+
# Client modules
|
|
10
|
+
"PurviewClient",
|
|
11
|
+
# CLI modules
|
|
12
|
+
"cli",
|
|
13
|
+
"account",
|
|
14
|
+
"entity",
|
|
15
|
+
"glossary",
|
|
16
|
+
"lineage",
|
|
17
|
+
"search",
|
|
18
|
+
"scan",
|
|
19
|
+
"types",
|
|
20
|
+
"relationship",
|
|
21
|
+
"management",
|
|
22
|
+
"policystore",
|
|
23
|
+
"insight",
|
|
24
|
+
"share",
|
|
25
|
+
"collections",
|
|
26
|
+
"uc",
|
|
27
|
+
]
|
purviewcli/__main__.py
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Main entry point for the purviewcli package.
|
|
4
|
+
Allows the CLI to be executed with: python -m purviewcli
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from purviewcli.cli.cli import main
|
|
8
|
+
|
|
9
|
+
if __name__ == '__main__':
|
|
10
|
+
import sys
|
|
11
|
+
if '--version' in sys.argv:
|
|
12
|
+
from purviewcli import __version__
|
|
13
|
+
print(f"Purview CLI version: {__version__}")
|
|
14
|
+
sys.exit(0)
|
|
15
|
+
main()
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Manage Purview account and collections using modular Click-based commands.
|
|
3
|
+
|
|
4
|
+
Usage:
|
|
5
|
+
account get-account Get account information
|
|
6
|
+
account get-access-keys Get account access keys
|
|
7
|
+
account regenerate-access-keys Regenerate account access keys
|
|
8
|
+
account update-account Update account information
|
|
9
|
+
account get-collections Get all collections
|
|
10
|
+
account get-collection Get specific collection information
|
|
11
|
+
account --help Show this help message and exit
|
|
12
|
+
|
|
13
|
+
Options:
|
|
14
|
+
-h --help Show this help message and exit
|
|
15
|
+
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
import json
|
|
19
|
+
import click
|
|
20
|
+
from rich.console import Console
|
|
21
|
+
|
|
22
|
+
console = Console()
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@click.group()
|
|
26
|
+
@click.pass_context
|
|
27
|
+
def account(ctx):
|
|
28
|
+
"""
|
|
29
|
+
Manage Purview account and collections.
|
|
30
|
+
"""
|
|
31
|
+
pass
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@account.command()
|
|
35
|
+
@click.pass_context
|
|
36
|
+
def get_account(ctx):
|
|
37
|
+
"""Get account information"""
|
|
38
|
+
try:
|
|
39
|
+
if ctx.obj.get("mock"):
|
|
40
|
+
console.print("[yellow]🎭 Mock: account get-account command[/yellow]")
|
|
41
|
+
console.print("[green][OK] Mock account get-account completed successfully[/green]")
|
|
42
|
+
return
|
|
43
|
+
|
|
44
|
+
args = {}
|
|
45
|
+
|
|
46
|
+
from purviewcli.client._account import Account
|
|
47
|
+
account_client = Account()
|
|
48
|
+
result = account_client.accountRead(args)
|
|
49
|
+
|
|
50
|
+
if result:
|
|
51
|
+
console.print("[green][OK] Account information retrieved successfully[/green]")
|
|
52
|
+
console.print(json.dumps(result, indent=2))
|
|
53
|
+
else:
|
|
54
|
+
console.print("[yellow][!] Account get-account completed with no result[/yellow]")
|
|
55
|
+
|
|
56
|
+
except Exception as e:
|
|
57
|
+
console.print(f"[red][X] Error executing account get-account: {str(e)}[/red]")
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
@account.command()
|
|
61
|
+
@click.pass_context
|
|
62
|
+
def get_access_keys(ctx):
|
|
63
|
+
"""Get account access keys"""
|
|
64
|
+
try:
|
|
65
|
+
if ctx.obj.get("mock"):
|
|
66
|
+
console.print("[yellow]🎭 Mock: account get-access-keys command[/yellow]")
|
|
67
|
+
console.print("[green][OK] Mock account get-access-keys completed successfully[/green]")
|
|
68
|
+
return
|
|
69
|
+
|
|
70
|
+
args = {}
|
|
71
|
+
|
|
72
|
+
from purviewcli.client._account import Account
|
|
73
|
+
account_client = Account()
|
|
74
|
+
result = account_client.accountReadAccessKeys(args)
|
|
75
|
+
|
|
76
|
+
if result:
|
|
77
|
+
console.print("[green][OK] Access keys retrieved successfully[/green]")
|
|
78
|
+
console.print(json.dumps(result, indent=2))
|
|
79
|
+
else:
|
|
80
|
+
console.print("[yellow][!] Account get-access-keys completed with no result[/yellow]")
|
|
81
|
+
|
|
82
|
+
except Exception as e:
|
|
83
|
+
console.print(f"[red][X] Error executing account get-access-keys: {str(e)}[/red]")
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
@account.command()
|
|
87
|
+
@click.option('--key-type', required=True,
|
|
88
|
+
type=click.Choice(['AtlasKafkaPrimaryKey', 'AtlasKafkaSecondaryKey']),
|
|
89
|
+
help='The access key type to regenerate')
|
|
90
|
+
@click.pass_context
|
|
91
|
+
def regenerate_access_keys(ctx, key_type):
|
|
92
|
+
"""Regenerate account access keys"""
|
|
93
|
+
try:
|
|
94
|
+
if ctx.obj.get("mock"):
|
|
95
|
+
console.print("[yellow]🎭 Mock: account regenerate-access-keys command[/yellow]")
|
|
96
|
+
console.print(f"[dim]Key Type: {key_type}[/dim]")
|
|
97
|
+
console.print("[green][OK] Mock account regenerate-access-keys completed successfully[/green]")
|
|
98
|
+
return
|
|
99
|
+
|
|
100
|
+
args = {"--keyType": key_type}
|
|
101
|
+
|
|
102
|
+
from purviewcli.client._account import Account
|
|
103
|
+
account_client = Account()
|
|
104
|
+
result = account_client.accountRegenerateAccessKey(args)
|
|
105
|
+
|
|
106
|
+
if result:
|
|
107
|
+
console.print("[green][OK] Access keys regenerated successfully[/green]")
|
|
108
|
+
console.print(json.dumps(result, indent=2))
|
|
109
|
+
else:
|
|
110
|
+
console.print("[yellow][!] Account regenerate-access-keys completed with no result[/yellow]")
|
|
111
|
+
|
|
112
|
+
except Exception as e:
|
|
113
|
+
console.print(f"[red][X] Error executing account regenerate-access-keys: {str(e)}[/red]")
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
@account.command()
|
|
117
|
+
@click.option('--friendly-name', required=True, help='The friendly name for the azure resource')
|
|
118
|
+
@click.pass_context
|
|
119
|
+
def update_account(ctx, friendly_name):
|
|
120
|
+
"""Update account information"""
|
|
121
|
+
try:
|
|
122
|
+
if ctx.obj.get("mock"):
|
|
123
|
+
console.print("[yellow]🎭 Mock: account update-account command[/yellow]")
|
|
124
|
+
console.print(f"[dim]Friendly Name: {friendly_name}[/dim]")
|
|
125
|
+
console.print("[green][OK] Mock account update-account completed successfully[/green]")
|
|
126
|
+
return
|
|
127
|
+
|
|
128
|
+
args = {"--friendlyName": friendly_name}
|
|
129
|
+
|
|
130
|
+
from purviewcli.client._account import Account
|
|
131
|
+
account_client = Account()
|
|
132
|
+
result = account_client.accountUpdate(args)
|
|
133
|
+
|
|
134
|
+
if result:
|
|
135
|
+
console.print("[green][OK] Account updated successfully[/green]")
|
|
136
|
+
console.print(json.dumps(result, indent=2))
|
|
137
|
+
else:
|
|
138
|
+
console.print("[yellow][!] Account update-account completed with no result[/yellow]")
|
|
139
|
+
|
|
140
|
+
except Exception as e:
|
|
141
|
+
console.print(f"[red][X] Error executing account update-account: {str(e)}[/red]")
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
@account.command()
|
|
145
|
+
@click.pass_context
|
|
146
|
+
def get_collections(ctx):
|
|
147
|
+
"""Get all collections"""
|
|
148
|
+
try:
|
|
149
|
+
if ctx.obj.get("mock"):
|
|
150
|
+
console.print("[yellow]🎭 Mock: account get-collections command[/yellow]")
|
|
151
|
+
console.print("[green][OK] Mock account get-collections completed successfully[/green]")
|
|
152
|
+
return
|
|
153
|
+
|
|
154
|
+
args = {}
|
|
155
|
+
|
|
156
|
+
from purviewcli.client._collections import Collections
|
|
157
|
+
account_client = Collections()
|
|
158
|
+
result = account_client.collectionsRead(args)
|
|
159
|
+
|
|
160
|
+
if result:
|
|
161
|
+
console.print("[green][OK] Collections retrieved successfully[/green]")
|
|
162
|
+
console.print(json.dumps(result, indent=2))
|
|
163
|
+
else:
|
|
164
|
+
console.print("[yellow][!] Account get-collections completed with no result[/yellow]")
|
|
165
|
+
|
|
166
|
+
except Exception as e:
|
|
167
|
+
console.print(f"[red][X] Error executing account get-collections: {str(e)}[/red]")
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
@account.command()
|
|
171
|
+
@click.option('--collection-name', required=True, help='The technical name of the collection')
|
|
172
|
+
@click.pass_context
|
|
173
|
+
def get_collection(ctx, collection_name):
|
|
174
|
+
"""Get specific collection information"""
|
|
175
|
+
try:
|
|
176
|
+
if ctx.obj.get("mock"):
|
|
177
|
+
console.print("[yellow]🎭 Mock: account get-collection command[/yellow]")
|
|
178
|
+
console.print(f"[dim]Collection Name: {collection_name}[/dim]")
|
|
179
|
+
console.print("[green][OK] Mock account get-collection completed successfully[/green]")
|
|
180
|
+
return
|
|
181
|
+
|
|
182
|
+
args = {"--collectionName": collection_name}
|
|
183
|
+
|
|
184
|
+
from purviewcli.client._collections import Collections
|
|
185
|
+
account_client = Collections()
|
|
186
|
+
result = account_client.collectionsRead(args)
|
|
187
|
+
|
|
188
|
+
if result:
|
|
189
|
+
console.print("[green][OK] Collection information retrieved successfully[/green]")
|
|
190
|
+
console.print(json.dumps(result, indent=2))
|
|
191
|
+
else:
|
|
192
|
+
console.print("[yellow][!] Account get-collection completed with no result[/yellow]")
|
|
193
|
+
|
|
194
|
+
except Exception as e:
|
|
195
|
+
console.print(f"[red][X] Error executing account get-collection: {str(e)}[/red]")
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
# Make the account group available for import
|
|
199
|
+
__all__ = ['account']
|
purviewcli/cli/cli.py
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Purview CLI (pvw) - Production Version
|
|
3
|
+
======================================
|
|
4
|
+
|
|
5
|
+
A comprehensive, automation-friendly command-line interface for Microsoft Purview.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import json
|
|
9
|
+
import sys
|
|
10
|
+
import re
|
|
11
|
+
import traceback
|
|
12
|
+
from datetime import datetime
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
from typing import Dict, List, Optional
|
|
15
|
+
|
|
16
|
+
import click
|
|
17
|
+
from rich.console import Console
|
|
18
|
+
|
|
19
|
+
console = Console()
|
|
20
|
+
|
|
21
|
+
# Import version for the CLI
|
|
22
|
+
try:
|
|
23
|
+
from purviewcli import __version__
|
|
24
|
+
except ImportError:
|
|
25
|
+
__version__ = "unknown"
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
# ============================================================================
|
|
29
|
+
# INDIVIDUAL CLI MODULE REGISTRATION SYSTEM
|
|
30
|
+
# ============================================================================
|
|
31
|
+
def register_individual_cli_modules(main_group):
|
|
32
|
+
"""
|
|
33
|
+
Register all CLI command groups as modular Click-based modules for full visibility and maintainability.
|
|
34
|
+
Each group is implemented in its own file in purviewcli/cli/ and exposes all real subcommands.
|
|
35
|
+
"""
|
|
36
|
+
try:
|
|
37
|
+
from .lineage import lineage
|
|
38
|
+
|
|
39
|
+
main_group.add_command(lineage)
|
|
40
|
+
except ImportError as e:
|
|
41
|
+
console.print(f"[yellow][!] Could not import lineage CLI module: {e}[/yellow]")
|
|
42
|
+
try:
|
|
43
|
+
from .account import account
|
|
44
|
+
|
|
45
|
+
main_group.add_command(account)
|
|
46
|
+
except ImportError as e:
|
|
47
|
+
console.print(f"[yellow][!] Could not import account CLI module: {e}[/yellow]")
|
|
48
|
+
try:
|
|
49
|
+
from .entity import entity
|
|
50
|
+
|
|
51
|
+
main_group.add_command(entity)
|
|
52
|
+
except ImportError as e:
|
|
53
|
+
console.print(f"[yellow][!] Could not import entity CLI module: {e}[/yellow]")
|
|
54
|
+
try:
|
|
55
|
+
from .insight import insight
|
|
56
|
+
|
|
57
|
+
main_group.add_command(insight)
|
|
58
|
+
except ImportError as e:
|
|
59
|
+
console.print(f"[yellow][!] Could not import insight CLI module: {e}[/yellow]")
|
|
60
|
+
try:
|
|
61
|
+
from .glossary import glossary
|
|
62
|
+
|
|
63
|
+
main_group.add_command(glossary)
|
|
64
|
+
except ImportError as e:
|
|
65
|
+
console.print(f"[yellow][!] Could not import glossary CLI module: {e}[/yellow]")
|
|
66
|
+
try:
|
|
67
|
+
from .management import management
|
|
68
|
+
|
|
69
|
+
main_group.add_command(management)
|
|
70
|
+
except ImportError as e:
|
|
71
|
+
console.print(f"[yellow][!] Could not import management CLI module: {e}[/yellow]")
|
|
72
|
+
try:
|
|
73
|
+
from .policystore import policystore
|
|
74
|
+
|
|
75
|
+
main_group.add_command(policystore)
|
|
76
|
+
except ImportError as e:
|
|
77
|
+
console.print(f"[yellow][!] Could not import policystore CLI module: {e}[/yellow]")
|
|
78
|
+
try:
|
|
79
|
+
from .relationship import relationship
|
|
80
|
+
|
|
81
|
+
main_group.add_command(relationship)
|
|
82
|
+
except ImportError as e:
|
|
83
|
+
console.print(f"[yellow][!] Could not import relationship CLI module: {e}[/yellow]")
|
|
84
|
+
try:
|
|
85
|
+
from .scan import scan
|
|
86
|
+
|
|
87
|
+
main_group.add_command(scan)
|
|
88
|
+
|
|
89
|
+
except ImportError as e:
|
|
90
|
+
console.print(f"[yellow][!] Could not import scan CLI module: {e}[/yellow]")
|
|
91
|
+
try:
|
|
92
|
+
from .search import search
|
|
93
|
+
|
|
94
|
+
main_group.add_command(search)
|
|
95
|
+
except ImportError as e:
|
|
96
|
+
console.print(f"[yellow][!] Could not import search CLI module: {e}[/yellow]")
|
|
97
|
+
try:
|
|
98
|
+
from .share import share
|
|
99
|
+
|
|
100
|
+
main_group.add_command(share)
|
|
101
|
+
except ImportError as e:
|
|
102
|
+
console.print(f"[yellow][!] Could not import share CLI module: {e}[/yellow]")
|
|
103
|
+
try:
|
|
104
|
+
from .types import types
|
|
105
|
+
main_group.add_command(types)
|
|
106
|
+
except ImportError as e:
|
|
107
|
+
console.print(f"[yellow][!] Could not import types CLI module: {e}[/yellow]")
|
|
108
|
+
try:
|
|
109
|
+
from .collections import collections
|
|
110
|
+
main_group.add_command(collections, name="collections")
|
|
111
|
+
# Removed domain alias to avoid conflicts with dedicated domain module
|
|
112
|
+
except ImportError as e:
|
|
113
|
+
console.print(f"[yellow][!] Could not import collections CLI module: {e}[/yellow]")
|
|
114
|
+
try:
|
|
115
|
+
from .unified_catalog import uc
|
|
116
|
+
|
|
117
|
+
main_group.add_command(uc) # Main Unified Catalog command
|
|
118
|
+
except ImportError as e:
|
|
119
|
+
console.print(f"[yellow][!] Could not import unified catalog (uc) CLI module: {e}[/yellow]")
|
|
120
|
+
try:
|
|
121
|
+
from .domain import domain
|
|
122
|
+
|
|
123
|
+
main_group.add_command(domain)
|
|
124
|
+
except ImportError as e:
|
|
125
|
+
console.print(f"[yellow][!] Could not import domain CLI module: {e}[/yellow]")
|
|
126
|
+
try:
|
|
127
|
+
from .workflow import workflow
|
|
128
|
+
|
|
129
|
+
main_group.add_command(workflow)
|
|
130
|
+
except ImportError as e:
|
|
131
|
+
console.print(f"[yellow][!] Could not import workflow CLI module: {e}[/yellow]")
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
@click.group()
|
|
135
|
+
@click.version_option(version=__version__, prog_name="pvw")
|
|
136
|
+
@click.option("--profile", help="Configuration profile to use")
|
|
137
|
+
@click.option("--account-name", help="Override Purview account name")
|
|
138
|
+
@click.option(
|
|
139
|
+
"--endpoint", help="Purview account endpoint (e.g. https://<your-account>.purview.azure.com)"
|
|
140
|
+
)
|
|
141
|
+
@click.option("--token", help="Azure AD access token for authentication")
|
|
142
|
+
@click.option("--debug", is_flag=True, help="Enable debug mode")
|
|
143
|
+
@click.option("--mock", is_flag=True, help="Mock mode - simulate commands without real API calls")
|
|
144
|
+
@click.pass_context
|
|
145
|
+
def main(ctx, profile, account_name, endpoint, token, debug, mock):
|
|
146
|
+
"""
|
|
147
|
+
Purview CLI with profile management and automation.
|
|
148
|
+
All command groups are registered as modular Click-based modules for full CLI visibility.
|
|
149
|
+
"""
|
|
150
|
+
ctx.ensure_object(dict)
|
|
151
|
+
|
|
152
|
+
if debug:
|
|
153
|
+
console.print("[cyan]Debug mode enabled[/cyan]")
|
|
154
|
+
if mock:
|
|
155
|
+
console.print("[yellow]Mock mode enabled - commands will be simulated[/yellow]")
|
|
156
|
+
|
|
157
|
+
# Store basic config
|
|
158
|
+
ctx.obj["account_name"] = account_name
|
|
159
|
+
ctx.obj["profile"] = profile
|
|
160
|
+
ctx.obj["debug"] = debug
|
|
161
|
+
ctx.obj["mock"] = mock
|
|
162
|
+
ctx.obj["endpoint"] = endpoint
|
|
163
|
+
ctx.obj["token"] = token
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
# Register all Click-based CLI modules after main is defined
|
|
167
|
+
register_individual_cli_modules(main)
|
|
168
|
+
|
|
169
|
+
if __name__ == "__main__":
|
|
170
|
+
main()
|