validio-cli 10.0.6__tar.gz → 10.1.0__tar.gz
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.
- {validio_cli-10.0.6 → validio_cli-10.1.0}/PKG-INFO +3 -3
- validio_cli-10.1.0/pyproject.toml +111 -0
- validio_cli-10.0.6/pyproject.toml → validio_cli-10.1.0/pyproject.toml.orig +7 -6
- {validio_cli-10.0.6 → validio_cli-10.1.0}/validio_cli/__init__.py +2 -2
- {validio_cli-10.0.6 → validio_cli-10.1.0}/validio_cli/bin/entities/code.py +58 -2
- {validio_cli-10.0.6 → validio_cli-10.1.0}/validio_cli/bin/entities/namespaces.py +3 -18
- {validio_cli-10.0.6 → validio_cli-10.1.0}/validio_cli/bin/entities/resources.py +1 -1
- {validio_cli-10.0.6 → validio_cli-10.1.0}/validio_cli/bin/entities/sources.py +3 -5
- validio_cli-10.1.0/validio_cli/bin/entities/validator_debug_queries.py +130 -0
- {validio_cli-10.0.6 → validio_cli-10.1.0}/validio_cli/bin/main.py +6 -0
- {validio_cli-10.0.6 → validio_cli-10.1.0}/README_PUBLIC.md +0 -0
- {validio_cli-10.0.6 → validio_cli-10.1.0}/validio_cli/bin/entities/channels.py +0 -0
- {validio_cli-10.0.6 → validio_cli-10.1.0}/validio_cli/bin/entities/config.py +0 -0
- {validio_cli-10.0.6 → validio_cli-10.1.0}/validio_cli/bin/entities/credentials.py +0 -0
- {validio_cli-10.0.6 → validio_cli-10.1.0}/validio_cli/bin/entities/dbt.py +0 -0
- {validio_cli-10.0.6 → validio_cli-10.1.0}/validio_cli/bin/entities/filters.py +0 -0
- {validio_cli-10.0.6 → validio_cli-10.1.0}/validio_cli/bin/entities/incidents.py +0 -0
- {validio_cli-10.0.6 → validio_cli-10.1.0}/validio_cli/bin/entities/integrations.py +0 -0
- {validio_cli-10.0.6 → validio_cli-10.1.0}/validio_cli/bin/entities/metrics.py +0 -0
- {validio_cli-10.0.6 → validio_cli-10.1.0}/validio_cli/bin/entities/notification_rules.py +0 -0
- {validio_cli-10.0.6 → validio_cli-10.1.0}/validio_cli/bin/entities/segmentations.py +0 -0
- {validio_cli-10.0.6 → validio_cli-10.1.0}/validio_cli/bin/entities/segments.py +0 -0
- {validio_cli-10.0.6 → validio_cli-10.1.0}/validio_cli/bin/entities/users.py +0 -0
- {validio_cli-10.0.6 → validio_cli-10.1.0}/validio_cli/bin/entities/validators.py +0 -0
- {validio_cli-10.0.6 → validio_cli-10.1.0}/validio_cli/bin/entities/windows.py +0 -0
- {validio_cli-10.0.6 → validio_cli-10.1.0}/validio_cli/components.py +0 -0
- {validio_cli-10.0.6 → validio_cli-10.1.0}/validio_cli/metadata.py +0 -0
- {validio_cli-10.0.6 → validio_cli-10.1.0}/validio_cli/namespace.py +0 -0
- {validio_cli-10.0.6 → validio_cli-10.1.0}/validio_cli/schema.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: validio-cli
|
|
3
|
-
Version: 10.0
|
|
3
|
+
Version: 10.1.0
|
|
4
4
|
Summary: CLI tool to interact with the Validio platform
|
|
5
5
|
Author: Validio
|
|
6
6
|
Author-email: Validio <support@validio.io>
|
|
@@ -11,9 +11,9 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
11
11
|
Classifier: Programming Language :: Python :: 3.12
|
|
12
12
|
Classifier: Programming Language :: Python :: 3.13
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.14
|
|
14
|
-
Requires-Dist: camel-converter>=
|
|
14
|
+
Requires-Dist: camel-converter>=5.1.0,<6
|
|
15
15
|
Requires-Dist: classdiff>=0.5.2,<0.6
|
|
16
|
-
Requires-Dist: typer
|
|
16
|
+
Requires-Dist: typer>=0.27.0,<0.28.0
|
|
17
17
|
Requires-Dist: prompt-toolkit>=3.0.38,<4
|
|
18
18
|
Requires-Dist: tabulate>=0.9.0,<0.11
|
|
19
19
|
Requires-Dist: types-tabulate>=0.9.0.2,<0.11
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "validio-cli"
|
|
3
|
+
version = "10.1.0"
|
|
4
|
+
description = "CLI tool to interact with the Validio platform"
|
|
5
|
+
requires-python = ">=3.10,<4"
|
|
6
|
+
readme = "README_PUBLIC.md"
|
|
7
|
+
license = "Apache-2.0"
|
|
8
|
+
classifiers = [
|
|
9
|
+
"Programming Language :: Python :: 3",
|
|
10
|
+
"Programming Language :: Python :: 3.10",
|
|
11
|
+
"Programming Language :: Python :: 3.11",
|
|
12
|
+
"Programming Language :: Python :: 3.12",
|
|
13
|
+
"Programming Language :: Python :: 3.13",
|
|
14
|
+
"Programming Language :: Python :: 3.14",
|
|
15
|
+
]
|
|
16
|
+
dependencies = [
|
|
17
|
+
"camel-converter>=5.1.0,<6",
|
|
18
|
+
"classdiff>=0.5.2,<0.6",
|
|
19
|
+
"typer>=0.27.0,<0.28.0",
|
|
20
|
+
"prompt-toolkit>=3.0.38,<4",
|
|
21
|
+
"tabulate>=0.9.0,<0.11",
|
|
22
|
+
"types-tabulate>=0.9.0.2,<0.11",
|
|
23
|
+
"validio-sdk",
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
[[project.authors]]
|
|
27
|
+
name = "Validio"
|
|
28
|
+
email = "support@validio.io"
|
|
29
|
+
|
|
30
|
+
[project.urls]
|
|
31
|
+
Homepage = "https://validio.io/"
|
|
32
|
+
Documentation = "https://docs.validio.io/"
|
|
33
|
+
|
|
34
|
+
[project.scripts]
|
|
35
|
+
validio = "validio_cli.bin.main:main"
|
|
36
|
+
|
|
37
|
+
[dependency-groups]
|
|
38
|
+
dev = [
|
|
39
|
+
"ruff==0.16.1",
|
|
40
|
+
"mypy>=1.2.0,<2",
|
|
41
|
+
"licensecheck>=2025.1.0,<2026",
|
|
42
|
+
"pytest>=9.0.3,<10",
|
|
43
|
+
"flameprof>=0.4,<0.5",
|
|
44
|
+
"validio-sdk",
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
[tool.uv]
|
|
48
|
+
default-groups = "all"
|
|
49
|
+
|
|
50
|
+
[tool.uv.sources.validio-sdk]
|
|
51
|
+
workspace = true
|
|
52
|
+
|
|
53
|
+
[tool.uv.build-backend]
|
|
54
|
+
module-name = ["validio_cli"]
|
|
55
|
+
module-root = ""
|
|
56
|
+
|
|
57
|
+
[tool.ruff]
|
|
58
|
+
fix = true
|
|
59
|
+
|
|
60
|
+
[tool.ruff.lint]
|
|
61
|
+
select = [
|
|
62
|
+
"ARG",
|
|
63
|
+
"C4",
|
|
64
|
+
"D",
|
|
65
|
+
"E",
|
|
66
|
+
"F",
|
|
67
|
+
"I",
|
|
68
|
+
"N",
|
|
69
|
+
"PIE",
|
|
70
|
+
"PL",
|
|
71
|
+
"PT",
|
|
72
|
+
"PTH",
|
|
73
|
+
"RET",
|
|
74
|
+
"RUF",
|
|
75
|
+
"SIM",
|
|
76
|
+
"UP",
|
|
77
|
+
"W",
|
|
78
|
+
]
|
|
79
|
+
ignore = [
|
|
80
|
+
"D203",
|
|
81
|
+
"D212",
|
|
82
|
+
"PLR0913",
|
|
83
|
+
"PLR0917",
|
|
84
|
+
"PLC0415",
|
|
85
|
+
]
|
|
86
|
+
|
|
87
|
+
[tool.ruff.lint.per-file-ignores]
|
|
88
|
+
"__init__.py" = ["D"]
|
|
89
|
+
"*/bin/*.py" = [
|
|
90
|
+
"D",
|
|
91
|
+
"UP007",
|
|
92
|
+
"UP045",
|
|
93
|
+
]
|
|
94
|
+
"examples/*.py" = ["D"]
|
|
95
|
+
|
|
96
|
+
[tool.mypy]
|
|
97
|
+
ignore_missing_imports = true
|
|
98
|
+
disallow_untyped_calls = true
|
|
99
|
+
disallow_untyped_defs = true
|
|
100
|
+
disallow_incomplete_defs = true
|
|
101
|
+
check_untyped_defs = true
|
|
102
|
+
disallow_untyped_decorators = true
|
|
103
|
+
|
|
104
|
+
[tool.licensecheck]
|
|
105
|
+
license = "Apache-2.0"
|
|
106
|
+
ignore_packages = ["MYPY-EXTENSIONS"]
|
|
107
|
+
zero = true
|
|
108
|
+
|
|
109
|
+
[build-system]
|
|
110
|
+
requires = ["uv_build>=0.12.3,<0.13.0"]
|
|
111
|
+
build-backend = "uv_build"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "validio-cli"
|
|
3
|
-
version = "10.0
|
|
3
|
+
version = "10.1.0"
|
|
4
4
|
description = "CLI tool to interact with the Validio platform"
|
|
5
5
|
authors = [{ name = "Validio", email = "support@validio.io" }]
|
|
6
6
|
requires-python = ">=3.10,<4"
|
|
@@ -15,9 +15,9 @@ classifiers = [
|
|
|
15
15
|
"Programming Language :: Python :: 3.14",
|
|
16
16
|
]
|
|
17
17
|
dependencies = [
|
|
18
|
-
"camel-converter>=
|
|
18
|
+
"camel-converter>=5.1.0,<6",
|
|
19
19
|
"classdiff>=0.5.2,<0.6",
|
|
20
|
-
"typer
|
|
20
|
+
"typer>=0.27.0,<0.28.0",
|
|
21
21
|
"prompt-toolkit>=3.0.38,<4",
|
|
22
22
|
"tabulate>=0.9.0,<0.11",
|
|
23
23
|
"types-tabulate>=0.9.0.2,<0.11",
|
|
@@ -33,10 +33,10 @@ validio = "validio_cli.bin.main:main"
|
|
|
33
33
|
|
|
34
34
|
[dependency-groups]
|
|
35
35
|
dev = [
|
|
36
|
-
"ruff==0.
|
|
36
|
+
"ruff==0.16.1",
|
|
37
37
|
"mypy>=1.2.0,<2",
|
|
38
38
|
"licensecheck>=2025.1.0,<2026",
|
|
39
|
-
"pytest>=
|
|
39
|
+
"pytest>=9.0.3,<10",
|
|
40
40
|
"flameprof>=0.4,<0.5",
|
|
41
41
|
"validio-sdk",
|
|
42
42
|
]
|
|
@@ -52,7 +52,7 @@ module-name = ["validio_cli"]
|
|
|
52
52
|
module-root = ""
|
|
53
53
|
|
|
54
54
|
[build-system]
|
|
55
|
-
requires = ["uv_build>=0.
|
|
55
|
+
requires = ["uv_build>=0.12.3,<0.13.0"]
|
|
56
56
|
build-backend = "uv_build"
|
|
57
57
|
|
|
58
58
|
[tool.ruff]
|
|
@@ -82,6 +82,7 @@ ignore = [
|
|
|
82
82
|
"D203", # `one-blank-line-before-class` Incompatible with D211
|
|
83
83
|
"D212", # `multi-line-summary-first-line` Incompatible with D213
|
|
84
84
|
"PLR0913", # `too-many-arguments` - Not relevant with only 6
|
|
85
|
+
"PLR0917", # `too-many-positional-arguments` - Same as PLR0913
|
|
85
86
|
"PLC0415", # Imports are intentionally lazy (circular dependencies / startup perf)
|
|
86
87
|
]
|
|
87
88
|
|
|
@@ -11,10 +11,10 @@ from pathlib import Path
|
|
|
11
11
|
from types import EllipsisType
|
|
12
12
|
from typing import Any, TypeVar
|
|
13
13
|
|
|
14
|
-
import click
|
|
15
14
|
import typer
|
|
16
15
|
from camel_converter import to_snake
|
|
17
16
|
from tabulate import tabulate
|
|
17
|
+
from typer._click.globals import get_current_context
|
|
18
18
|
from validio_sdk import config
|
|
19
19
|
from validio_sdk._api.api import APIClient
|
|
20
20
|
from validio_sdk.client import USER_AGENT as SDK_USER_AGENT
|
|
@@ -108,7 +108,7 @@ def _cli_headers(iac: bool = False) -> dict[str, str]:
|
|
|
108
108
|
"""
|
|
109
109
|
headers: dict[str, str] = {}
|
|
110
110
|
|
|
111
|
-
ctx =
|
|
111
|
+
ctx = get_current_context(silent=True)
|
|
112
112
|
if ctx is not None:
|
|
113
113
|
# `command_path` is e.g. "validio channels get",
|
|
114
114
|
# drop the program name to get the command itself.
|
|
@@ -20,7 +20,10 @@ from validio_sdk.resource._resource import (
|
|
|
20
20
|
ResourceDeprecation,
|
|
21
21
|
ResourceFeatureNotice,
|
|
22
22
|
)
|
|
23
|
-
from validio_sdk.resource._util import
|
|
23
|
+
from validio_sdk.resource._util import (
|
|
24
|
+
SourceSchemaInferenceSkip,
|
|
25
|
+
SourceSchemaReinference,
|
|
26
|
+
)
|
|
24
27
|
from validio_sdk.resource.replacement import (
|
|
25
28
|
ImmutableFieldReplacementReason,
|
|
26
29
|
RecreateOnChangeReplacementReason,
|
|
@@ -130,6 +133,26 @@ update_all_schemas_option = typer.Option(
|
|
|
130
133
|
),
|
|
131
134
|
)
|
|
132
135
|
|
|
136
|
+
skip_schema_inference_option = typer.Option(
|
|
137
|
+
[],
|
|
138
|
+
help=(
|
|
139
|
+
f"{BETA_BANNER} "
|
|
140
|
+
"Specify a Source name to create without inferring its schema. This will"
|
|
141
|
+
" fallback to the corresponding schema in the Validio catalog. You can use"
|
|
142
|
+
" --skip-schema-inference src1 --skip-schema-inference src2 to specify"
|
|
143
|
+
" multiple Sources."
|
|
144
|
+
),
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
skip_all_schema_inference_option = typer.Option(
|
|
148
|
+
False,
|
|
149
|
+
help=(
|
|
150
|
+
f"{BETA_BANNER} "
|
|
151
|
+
"Similar to --skip-schema-inference. Skips schema inference for all Sources"
|
|
152
|
+
" being created"
|
|
153
|
+
),
|
|
154
|
+
)
|
|
155
|
+
|
|
133
156
|
show_progress_option = typer.Option(
|
|
134
157
|
sys.stdout.isatty(),
|
|
135
158
|
help=(
|
|
@@ -172,6 +195,8 @@ async def plan(
|
|
|
172
195
|
config_dir: str = ConfigDir,
|
|
173
196
|
update_schema: list[str] = update_schema_option,
|
|
174
197
|
update_all_schemas: bool = update_all_schemas_option,
|
|
198
|
+
skip_schema_inference: list[str] = skip_schema_inference_option,
|
|
199
|
+
skip_all_schema_inference: bool = skip_all_schema_inference_option,
|
|
175
200
|
show_schema: bool = show_schema_option,
|
|
176
201
|
diff_output: DiffOutput = diff_option,
|
|
177
202
|
destroy: bool = destroy_option,
|
|
@@ -184,6 +209,7 @@ async def plan(
|
|
|
184
209
|
segmentation: list[str] = target_option("segmentation"),
|
|
185
210
|
source: list[str] = target_option("source"),
|
|
186
211
|
validator: list[str] = target_option("validator"),
|
|
212
|
+
validator_debug_query: list[str] = target_option("validator-debug-query"),
|
|
187
213
|
window: list[str] = target_option("window"),
|
|
188
214
|
progress: bool = show_progress_option,
|
|
189
215
|
) -> None:
|
|
@@ -193,6 +219,9 @@ async def plan(
|
|
|
193
219
|
schema_reinference = create_source_schema_reinference(
|
|
194
220
|
update_schema, update_all_schemas
|
|
195
221
|
)
|
|
222
|
+
schema_inference_skip = create_source_schema_inference_skip(
|
|
223
|
+
skip_schema_inference, skip_all_schema_inference
|
|
224
|
+
)
|
|
196
225
|
|
|
197
226
|
namespace = get_namespace(dir_path)
|
|
198
227
|
await _plan(
|
|
@@ -200,6 +229,7 @@ async def plan(
|
|
|
200
229
|
client=client,
|
|
201
230
|
directory=dir_path,
|
|
202
231
|
schema_reinference=schema_reinference,
|
|
232
|
+
schema_inference_skip=schema_inference_skip,
|
|
203
233
|
destroy=destroy,
|
|
204
234
|
no_capture=no_capture,
|
|
205
235
|
color=color,
|
|
@@ -214,6 +244,7 @@ async def plan(
|
|
|
214
244
|
segmentations=set(segmentation),
|
|
215
245
|
sources=set(source),
|
|
216
246
|
validators=set(validator),
|
|
247
|
+
validator_debug_queries=set(validator_debug_query),
|
|
217
248
|
windows=set(window),
|
|
218
249
|
),
|
|
219
250
|
show_progress=progress,
|
|
@@ -230,6 +261,8 @@ async def apply(
|
|
|
230
261
|
config_dir: str = ConfigDir,
|
|
231
262
|
update_schema: list[str] = update_schema_option,
|
|
232
263
|
update_all_schemas: bool = update_all_schemas_option,
|
|
264
|
+
skip_schema_inference: list[str] = skip_schema_inference_option,
|
|
265
|
+
skip_all_schema_inference: bool = skip_all_schema_inference_option,
|
|
233
266
|
show_schema: bool = show_schema_option,
|
|
234
267
|
diff_output: DiffOutput = diff_option,
|
|
235
268
|
destroy: bool = destroy_option,
|
|
@@ -242,6 +275,7 @@ async def apply(
|
|
|
242
275
|
segmentation: list[str] = target_option("segmentation"),
|
|
243
276
|
source: list[str] = target_option("source"),
|
|
244
277
|
validator: list[str] = target_option("validator"),
|
|
278
|
+
validator_debug_query: list[str] = target_option("validator-debug-query"),
|
|
245
279
|
window: list[str] = target_option("window"),
|
|
246
280
|
progress: bool = show_progress_option,
|
|
247
281
|
test_credentials: bool = typer.Option(
|
|
@@ -263,6 +297,9 @@ async def apply(
|
|
|
263
297
|
schema_reinference = create_source_schema_reinference(
|
|
264
298
|
update_schema, update_all_schemas
|
|
265
299
|
)
|
|
300
|
+
schema_inference_skip = create_source_schema_inference_skip(
|
|
301
|
+
skip_schema_inference, skip_all_schema_inference
|
|
302
|
+
)
|
|
266
303
|
|
|
267
304
|
namespace = get_namespace(dir_path)
|
|
268
305
|
plan_result = await _plan(
|
|
@@ -270,6 +307,7 @@ async def apply(
|
|
|
270
307
|
client=client,
|
|
271
308
|
directory=dir_path,
|
|
272
309
|
schema_reinference=schema_reinference,
|
|
310
|
+
schema_inference_skip=schema_inference_skip,
|
|
273
311
|
destroy=destroy,
|
|
274
312
|
no_capture=no_capture,
|
|
275
313
|
color=color,
|
|
@@ -284,6 +322,7 @@ async def apply(
|
|
|
284
322
|
segmentations=set(segmentation),
|
|
285
323
|
sources=set(source),
|
|
286
324
|
validators=set(validator),
|
|
325
|
+
validator_debug_queries=set(validator_debug_query),
|
|
287
326
|
windows=set(window),
|
|
288
327
|
),
|
|
289
328
|
show_progress=progress,
|
|
@@ -308,6 +347,7 @@ async def apply(
|
|
|
308
347
|
show_progress=progress,
|
|
309
348
|
dry_run_sql=dry_run_sql,
|
|
310
349
|
test_credentials=test_credentials,
|
|
350
|
+
schema_inference_skip=schema_inference_skip,
|
|
311
351
|
)
|
|
312
352
|
|
|
313
353
|
print(
|
|
@@ -414,7 +454,7 @@ async def _import(
|
|
|
414
454
|
tags_ctx=plan_result.tags_context,
|
|
415
455
|
include_schema=include_schema,
|
|
416
456
|
)
|
|
417
|
-
output.write_text(s)
|
|
457
|
+
output.write_text(s, encoding="utf-8")
|
|
418
458
|
print(f"Generated file {output.absolute()}")
|
|
419
459
|
|
|
420
460
|
|
|
@@ -435,6 +475,7 @@ async def _plan(
|
|
|
435
475
|
destroy: bool,
|
|
436
476
|
no_capture: bool,
|
|
437
477
|
color: bool,
|
|
478
|
+
schema_inference_skip: SourceSchemaInferenceSkip = SourceSchemaInferenceSkip(),
|
|
438
479
|
show_schema: bool = False,
|
|
439
480
|
diff_output: DiffOutput = DiffOutput.FULL,
|
|
440
481
|
show_secrets: bool = False,
|
|
@@ -447,6 +488,7 @@ async def _plan(
|
|
|
447
488
|
client=client,
|
|
448
489
|
directory=directory,
|
|
449
490
|
schema_reinference=schema_reinference,
|
|
491
|
+
schema_inference_skip=schema_inference_skip,
|
|
450
492
|
destroy=destroy,
|
|
451
493
|
no_capture=no_capture,
|
|
452
494
|
show_secrets=show_secrets,
|
|
@@ -741,6 +783,20 @@ def create_source_schema_reinference(
|
|
|
741
783
|
)
|
|
742
784
|
|
|
743
785
|
|
|
786
|
+
def create_source_schema_inference_skip(
|
|
787
|
+
sources_to_skip: list[str], skip_all: bool
|
|
788
|
+
) -> SourceSchemaInferenceSkip:
|
|
789
|
+
source_names = None
|
|
790
|
+
if skip_all:
|
|
791
|
+
source_names = []
|
|
792
|
+
elif len(sources_to_skip) > 0:
|
|
793
|
+
source_names = sources_to_skip
|
|
794
|
+
|
|
795
|
+
return SourceSchemaInferenceSkip(
|
|
796
|
+
set(source_names) if source_names is not None else None
|
|
797
|
+
)
|
|
798
|
+
|
|
799
|
+
|
|
744
800
|
def _print_no_changes() -> None:
|
|
745
801
|
print("No changes. The configuration is up-to-date!")
|
|
746
802
|
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
from typing import Any, Optional
|
|
2
2
|
|
|
3
|
-
import click
|
|
4
3
|
import typer
|
|
5
4
|
from validio_sdk import ValidioError
|
|
6
5
|
|
|
@@ -15,21 +14,7 @@ from validio_cli import (
|
|
|
15
14
|
output_text,
|
|
16
15
|
)
|
|
17
16
|
|
|
18
|
-
|
|
19
|
-
class RoleSuggestion(click.ParamType):
|
|
20
|
-
name = "role"
|
|
21
|
-
|
|
22
|
-
def get_metavar(self, _: click.Parameter) -> str | None:
|
|
23
|
-
return "[Admin|Editor|Viewer|<Custom>]"
|
|
24
|
-
|
|
25
|
-
def convert(
|
|
26
|
-
self,
|
|
27
|
-
value: Any,
|
|
28
|
-
_param: click.Parameter | None,
|
|
29
|
-
_ctx: click.Context | None,
|
|
30
|
-
) -> Any:
|
|
31
|
-
return value
|
|
32
|
-
|
|
17
|
+
ROLE_METAVAR = "[Admin|Editor|Viewer|<Custom>]"
|
|
33
18
|
|
|
34
19
|
app = AsyncTyper(help="Namespaces used to separate resources")
|
|
35
20
|
|
|
@@ -63,7 +48,7 @@ async def create(
|
|
|
63
48
|
identifier: str = typer.Argument(..., help="Namespace name"),
|
|
64
49
|
role: str = typer.Option(
|
|
65
50
|
None,
|
|
66
|
-
|
|
51
|
+
metavar=ROLE_METAVAR,
|
|
67
52
|
help="The role (name or id) to assign --api-key and --member",
|
|
68
53
|
),
|
|
69
54
|
api_key: list[str] = typer.Option(
|
|
@@ -134,7 +119,7 @@ async def update(
|
|
|
134
119
|
identifier: str = typer.Argument(..., help="Namespace name"),
|
|
135
120
|
role: str = typer.Option(
|
|
136
121
|
None,
|
|
137
|
-
|
|
122
|
+
metavar=ROLE_METAVAR,
|
|
138
123
|
help="The role (name or id) to assign --api-key and --member",
|
|
139
124
|
),
|
|
140
125
|
api_key: list[str] = typer.Option(
|
|
@@ -113,7 +113,7 @@ def _read_resource_file(file: pathlib.Path) -> dict:
|
|
|
113
113
|
if not file.is_file():
|
|
114
114
|
raise ValidioError(f"'{file.absolute()}' is not a file")
|
|
115
115
|
|
|
116
|
-
obj = json.loads(file.read_text())
|
|
116
|
+
obj = json.loads(file.read_text(encoding="utf-8"))
|
|
117
117
|
if not isinstance(obj, dict):
|
|
118
118
|
raise ValidioError(f"expected json object in resource file: got {type(obj)}")
|
|
119
119
|
|
|
@@ -4,7 +4,6 @@ import uuid
|
|
|
4
4
|
from pathlib import Path
|
|
5
5
|
from typing import Any, Optional, cast
|
|
6
6
|
|
|
7
|
-
import click
|
|
8
7
|
import typer
|
|
9
8
|
from prompt_toolkit import PromptSession
|
|
10
9
|
from prompt_toolkit.completion import WordCompleter
|
|
@@ -283,6 +282,7 @@ async def reset(
|
|
|
283
282
|
|
|
284
283
|
@infer_schema_app.callback(invoke_without_command=True)
|
|
285
284
|
def main(
|
|
285
|
+
ctx: typer.Context,
|
|
286
286
|
interactive: bool = typer.Option(
|
|
287
287
|
False, "--interactive", "-i", help="Infer schema with an interactive prompt"
|
|
288
288
|
),
|
|
@@ -290,8 +290,6 @@ def main(
|
|
|
290
290
|
filename: Path = schema_filename_option("schema"),
|
|
291
291
|
namespace: str = Namespace(),
|
|
292
292
|
) -> None:
|
|
293
|
-
ctx = click.get_current_context()
|
|
294
|
-
|
|
295
293
|
# A subcommand was run prior to this, nothing todo
|
|
296
294
|
if ctx.invoked_subcommand is not None:
|
|
297
295
|
return None
|
|
@@ -302,7 +300,7 @@ def main(
|
|
|
302
300
|
|
|
303
301
|
# A flag for this command was used but not interactive, print the help as if
|
|
304
302
|
# no command was given
|
|
305
|
-
|
|
303
|
+
typer.echo(ctx.get_help())
|
|
306
304
|
|
|
307
305
|
return None
|
|
308
306
|
|
|
@@ -955,7 +953,7 @@ async def _infer_schema_bigquery(
|
|
|
955
953
|
|
|
956
954
|
|
|
957
955
|
def _write_schema(filename: Path, schema: Any) -> None:
|
|
958
|
-
filename.write_text(json.dumps(schema, indent=2))
|
|
956
|
+
filename.write_text(json.dumps(schema, indent=2), encoding="utf-8")
|
|
959
957
|
|
|
960
958
|
print(f"Schema written to {filename}")
|
|
961
959
|
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import typer
|
|
2
|
+
from validio_sdk._api.api import APIClient
|
|
3
|
+
from validio_sdk.config import ValidioConfig
|
|
4
|
+
from validio_sdk.exception import ValidioError
|
|
5
|
+
|
|
6
|
+
from validio_cli import (
|
|
7
|
+
AsyncTyper,
|
|
8
|
+
ConfigDir,
|
|
9
|
+
Identifier,
|
|
10
|
+
Identifiers,
|
|
11
|
+
Namespace,
|
|
12
|
+
OutputFormat,
|
|
13
|
+
OutputFormatOption,
|
|
14
|
+
OutputSettings,
|
|
15
|
+
get_client,
|
|
16
|
+
output_json,
|
|
17
|
+
output_ok_or_error,
|
|
18
|
+
output_text,
|
|
19
|
+
)
|
|
20
|
+
from validio_cli.bin.entities.validators import get_validator_id
|
|
21
|
+
from validio_cli.namespace import get_namespace
|
|
22
|
+
|
|
23
|
+
app = AsyncTyper(help="Debug queries saved on validators")
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@app.async_command(help="List validator debug queries")
|
|
27
|
+
async def get(
|
|
28
|
+
config_dir: str = ConfigDir,
|
|
29
|
+
output_format: OutputFormat = OutputFormatOption,
|
|
30
|
+
namespace: str = Namespace(),
|
|
31
|
+
identifier: str = Identifier,
|
|
32
|
+
validator: str = typer.Option(
|
|
33
|
+
None, help="List debug queries for this Validator (name or ID)"
|
|
34
|
+
),
|
|
35
|
+
) -> None:
|
|
36
|
+
if identifier and validator:
|
|
37
|
+
raise ValidioError("--validator can't be used together with an identifier")
|
|
38
|
+
|
|
39
|
+
vc, cfg = get_client(config_dir)
|
|
40
|
+
|
|
41
|
+
validator_id = (
|
|
42
|
+
await get_validator_id(vc, cfg, validator, namespace) if validator else None
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
debug_queries = await vc.get_validator_debug_queries(
|
|
46
|
+
validator_debug_query_id=identifier,
|
|
47
|
+
validator_id=validator_id,
|
|
48
|
+
namespace_id=get_namespace(namespace, cfg),
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
if output_format == OutputFormat.JSON:
|
|
52
|
+
return output_json(debug_queries, identifier)
|
|
53
|
+
|
|
54
|
+
return output_text(
|
|
55
|
+
debug_queries,
|
|
56
|
+
fields={
|
|
57
|
+
"name": OutputSettings(attribute_name="resourceName"),
|
|
58
|
+
"validator": OutputSettings(
|
|
59
|
+
reformat=lambda validator: validator["resourceName"]
|
|
60
|
+
),
|
|
61
|
+
"default": OutputSettings(attribute_name="defaultQuery"),
|
|
62
|
+
"age": OutputSettings.string_as_datetime(attribute_name="createdAt"),
|
|
63
|
+
},
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
@app.async_command(help="Delete validator debug query")
|
|
68
|
+
async def delete(
|
|
69
|
+
config_dir: str = ConfigDir,
|
|
70
|
+
output_format: OutputFormat = OutputFormatOption,
|
|
71
|
+
namespace: str = Namespace(),
|
|
72
|
+
identifiers: list[str] = Identifiers,
|
|
73
|
+
) -> None:
|
|
74
|
+
if not identifiers:
|
|
75
|
+
raise ValidioError("no identifiers are provided")
|
|
76
|
+
|
|
77
|
+
vc, cfg = get_client(config_dir)
|
|
78
|
+
|
|
79
|
+
debug_query_ids = [
|
|
80
|
+
debug_query_id
|
|
81
|
+
for debug_query_id in [
|
|
82
|
+
await get_validator_debug_query_id(vc, cfg, identifier, namespace)
|
|
83
|
+
for identifier in identifiers
|
|
84
|
+
]
|
|
85
|
+
if debug_query_id
|
|
86
|
+
]
|
|
87
|
+
|
|
88
|
+
result = await vc.delete_validator_debug_queries(debug_query_ids)
|
|
89
|
+
|
|
90
|
+
if output_format == OutputFormat.JSON:
|
|
91
|
+
return output_json(result)
|
|
92
|
+
|
|
93
|
+
return output_ok_or_error(result)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
async def get_validator_debug_query_id(
|
|
97
|
+
vc: APIClient, cfg: ValidioConfig, identifier: str, namespace: str
|
|
98
|
+
) -> str | None:
|
|
99
|
+
"""
|
|
100
|
+
Ensure the identifier is a resource id.
|
|
101
|
+
|
|
102
|
+
If it doesn't have the expected prefix, do a resource lookup by name.
|
|
103
|
+
"""
|
|
104
|
+
identifier_type = "validator debug query"
|
|
105
|
+
prefix = "VDQ_"
|
|
106
|
+
|
|
107
|
+
if not identifier:
|
|
108
|
+
print(f"Missing {identifier_type} id or name")
|
|
109
|
+
return None
|
|
110
|
+
|
|
111
|
+
if identifier.startswith(prefix):
|
|
112
|
+
return identifier
|
|
113
|
+
|
|
114
|
+
resource = await vc.get_validator_debug_queries(
|
|
115
|
+
validator_debug_query_id=identifier,
|
|
116
|
+
namespace_id=get_namespace(namespace, cfg),
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
if resource is None:
|
|
120
|
+
print(f"No {identifier_type} with name or id {identifier} found")
|
|
121
|
+
return None
|
|
122
|
+
|
|
123
|
+
if not isinstance(resource, dict):
|
|
124
|
+
raise ValidioError("failed to get validator debug query id")
|
|
125
|
+
|
|
126
|
+
return resource["id"]
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
if __name__ == "__main__":
|
|
130
|
+
app()
|
|
@@ -30,6 +30,7 @@ from validio_cli.bin.entities import (
|
|
|
30
30
|
segments,
|
|
31
31
|
sources,
|
|
32
32
|
users,
|
|
33
|
+
validator_debug_queries,
|
|
33
34
|
validators,
|
|
34
35
|
windows,
|
|
35
36
|
)
|
|
@@ -78,6 +79,11 @@ app.add_typer(segments.app, no_args_is_help=True, name="segments")
|
|
|
78
79
|
app.add_typer(sources.app, no_args_is_help=True, name="sources")
|
|
79
80
|
app.add_typer(users.app, no_args_is_help=True, name="users")
|
|
80
81
|
app.add_typer(validators.app, no_args_is_help=True, name="validators")
|
|
82
|
+
app.add_typer(
|
|
83
|
+
validator_debug_queries.app,
|
|
84
|
+
no_args_is_help=True,
|
|
85
|
+
name="validator-debug-queries",
|
|
86
|
+
)
|
|
81
87
|
app.add_typer(windows.app, no_args_is_help=True, name="windows")
|
|
82
88
|
|
|
83
89
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|