tabsdata-cli 2.0.0__cp312-abi3-win_amd64.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.
Files changed (39) hide show
  1. tabsdata_cli-2.0.0.data/purelib/tabsdatak/cli/__init__.py +5 -0
  2. tabsdata_cli-2.0.0.data/purelib/tabsdatak/cli/_registry.py +78 -0
  3. tabsdata_cli-2.0.0.data/purelib/tabsdatak/cli/assets/manifest/BANNER +5 -0
  4. tabsdata_cli-2.0.0.data/purelib/tabsdatak/cli/assets/manifest/LICENSE +3 -0
  5. tabsdata_cli-2.0.0.data/purelib/tabsdatak/cli/assets/manifest/README-PyPi.md +8 -0
  6. tabsdata_cli-2.0.0.data/purelib/tabsdatak/cli/assets/manifest/RELEASE-NOTES +1 -0
  7. tabsdata_cli-2.0.0.data/purelib/tabsdatak/cli/assets/manifest/THIRD-PARTY +3 -0
  8. tabsdata_cli-2.0.0.data/purelib/tabsdatak/cli/assets/manifest/VERSION +1 -0
  9. tabsdata_cli-2.0.0.data/purelib/tabsdatak/cli/cli_utils.py +993 -0
  10. tabsdata_cli-2.0.0.data/purelib/tabsdatak/cli/shell.py +390 -0
  11. tabsdata_cli-2.0.0.data/purelib/tabsdatak/cli/td/__init__.py +3 -0
  12. tabsdata_cli-2.0.0.data/purelib/tabsdatak/cli/td/auth_group.py +197 -0
  13. tabsdata_cli-2.0.0.data/purelib/tabsdatak/cli/td/cli.py +508 -0
  14. tabsdata_cli-2.0.0.data/purelib/tabsdatak/cli/td/collection_group.py +458 -0
  15. tabsdata_cli-2.0.0.data/purelib/tabsdatak/cli/td/config_utils.py +93 -0
  16. tabsdata_cli-2.0.0.data/purelib/tabsdatak/cli/td/connection_group.py +159 -0
  17. tabsdata_cli-2.0.0.data/purelib/tabsdatak/cli/td/examples_group.py +206 -0
  18. tabsdata_cli-2.0.0.data/purelib/tabsdatak/cli/td/execution_utils.py +429 -0
  19. tabsdata_cli-2.0.0.data/purelib/tabsdatak/cli/td/fn_group.py +1109 -0
  20. tabsdata_cli-2.0.0.data/purelib/tabsdatak/cli/td/fnrun_group.py +285 -0
  21. tabsdata_cli-2.0.0.data/purelib/tabsdatak/cli/td/group_group.py +184 -0
  22. tabsdata_cli-2.0.0.data/purelib/tabsdatak/cli/td/metrics_group.py +323 -0
  23. tabsdata_cli-2.0.0.data/purelib/tabsdatak/cli/td/permission_group.py +259 -0
  24. tabsdata_cli-2.0.0.data/purelib/tabsdatak/cli/td/plan_group.py +324 -0
  25. tabsdata_cli-2.0.0.data/purelib/tabsdatak/cli/td/project_group.py +170 -0
  26. tabsdata_cli-2.0.0.data/purelib/tabsdatak/cli/td/role_group.py +630 -0
  27. tabsdata_cli-2.0.0.data/purelib/tabsdatak/cli/td/settings_group.py +344 -0
  28. tabsdata_cli-2.0.0.data/purelib/tabsdatak/cli/td/table_group.py +600 -0
  29. tabsdata_cli-2.0.0.data/purelib/tabsdatak/cli/td/trigger_group.py +338 -0
  30. tabsdata_cli-2.0.0.data/purelib/tabsdatak/cli/td/trx_group.py +329 -0
  31. tabsdata_cli-2.0.0.data/purelib/tabsdatak/cli/td/user_group.py +200 -0
  32. tabsdata_cli-2.0.0.data/purelib/tabsdatak/cli/td/worker_group.py +185 -0
  33. tabsdata_cli-2.0.0.data/purelib/tabsdatak/cli/template.py +781 -0
  34. tabsdata_cli-2.0.0.data/purelib/tabsdatak/py.typed +0 -0
  35. tabsdata_cli-2.0.0.dist-info/METADATA +39 -0
  36. tabsdata_cli-2.0.0.dist-info/RECORD +39 -0
  37. tabsdata_cli-2.0.0.dist-info/WHEEL +5 -0
  38. tabsdata_cli-2.0.0.dist-info/licenses/src/main/python/tabsdatak/cli/assets/manifest/LICENSE +3 -0
  39. tabsdata_cli-2.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,344 @@
1
+ #
2
+ # Copyright 2026 Tabsdata Inc.
3
+ #
4
+
5
+
6
+ import rich_click as click
7
+
8
+ from tabsdatak.cli._registry import cli_command
9
+ from tabsdatak.cli.cli_utils import (
10
+ DISABLED,
11
+ ENABLED,
12
+ OPTION_HINTS,
13
+ OPTION_PROMPT,
14
+ OPTION_SERVER,
15
+ PIN_COLLECTION,
16
+ PIN_PROJECT,
17
+ SERVER_URL_DEFAULTS_HELP,
18
+ clear_current_cli_option,
19
+ cli_option_enabled,
20
+ configured_server,
21
+ format_option,
22
+ get_current_cli_option,
23
+ get_pin,
24
+ hint_common_solutions,
25
+ render,
26
+ set_cli_option_enabled,
27
+ set_current_cli_option,
28
+ set_pin,
29
+ store_cli_options,
30
+ )
31
+
32
+ _NOTHING_TO_SET = (
33
+ "Nothing to set. Specify at least one setting: --hints true|false, "
34
+ "--prompt true|false, --server SERVER, --proj PROJECT and/or "
35
+ "--coll COLLECTION."
36
+ )
37
+ _NOTHING_TO_UNSET = (
38
+ "Nothing to unset. Specify at least one setting: --hints, --prompt, "
39
+ "--server, --proj and/or --coll -- or --all for every one of them."
40
+ )
41
+
42
+ _TRUE = "true"
43
+ _FALSE = "false"
44
+ # The on/off settings take the value explicitly, so a command reads as what it
45
+ # leaves behind; both default to true, which is what `tdk unset` restores. The
46
+ # same two words render them in `tdk settings`.
47
+ _BOOL = click.Choice((_TRUE, _FALSE))
48
+
49
+
50
+ @cli_command
51
+ @click.command("set")
52
+ @click.option(
53
+ "--hints",
54
+ type=_BOOL,
55
+ help="Show the hints the CLI adds to errors. Default: true.",
56
+ )
57
+ @click.option(
58
+ "--prompt",
59
+ type=_BOOL,
60
+ help=(
61
+ "Prompt for a value a command needs but was not given. Default: true; "
62
+ "'tdk set --prompt false' is the standing form of the root "
63
+ "'--no-prompt' flag."
64
+ ),
65
+ )
66
+ @click.option(
67
+ "--server",
68
+ "url",
69
+ metavar="SERVER",
70
+ help=(
71
+ "URL of the Tabsdata Server 'tdk login' uses without '--server'. "
72
+ + SERVER_URL_DEFAULTS_HELP
73
+ ),
74
+ )
75
+ @click.option(
76
+ "--proj",
77
+ "-P",
78
+ "project",
79
+ help="Project to pin as the default of project-scoped commands.",
80
+ )
81
+ @click.option(
82
+ "--coll",
83
+ "-c",
84
+ "collection",
85
+ help="Collection to pin (requires a pinned project).",
86
+ )
87
+ @click.pass_context
88
+ def set_setting(
89
+ ctx: click.Context,
90
+ hints: str,
91
+ prompt: str,
92
+ url: str,
93
+ project: str,
94
+ collection: str,
95
+ ):
96
+ """Give a setting a value.
97
+
98
+ Settings are persisted in 'options.json' under the Tabsdata directory
99
+ ('~/.tabsdata') and apply to every later invocation; 'tdk unset' drops them
100
+ back to their default and 'tdk settings' shows them. More than one can be
101
+ set at once.
102
+
103
+ Examples:
104
+ tdk set --hints false
105
+ tdk set --prompt false
106
+ tdk set --server http://127.0.0.1:2457
107
+ tdk set --server 127.0.0.1 # http://127.0.0.1:2457
108
+ tdk set --proj sales
109
+ tdk set --proj sales --coll orders
110
+ """
111
+ if hints is None and prompt is None and not (url or project or collection):
112
+ raise click.UsageError(_NOTHING_TO_SET)
113
+ if hints is not None:
114
+ _set_enabled(ctx, OPTION_HINTS, hints == _TRUE)
115
+ if prompt is not None:
116
+ _set_enabled(ctx, OPTION_PROMPT, prompt == _TRUE)
117
+ if url:
118
+ _set_server(ctx, url)
119
+ if project or collection:
120
+ _pin(ctx, project, collection)
121
+ store_cli_options(ctx)
122
+
123
+
124
+ @cli_command
125
+ @click.command("unset")
126
+ @click.option("--hints", is_flag=True, help="Restore the hints default (true).")
127
+ @click.option(
128
+ "--prompt",
129
+ is_flag=True,
130
+ help="Restore the prompting default (true).",
131
+ )
132
+ @click.option("--server", "url", is_flag=True, help="Clear the configured server.")
133
+ @click.option(
134
+ "--proj",
135
+ "-P",
136
+ "project",
137
+ is_flag=True,
138
+ help=(
139
+ "Unpin the project. Unpins the collection too, since a collection pin "
140
+ "only resolves under a project."
141
+ ),
142
+ )
143
+ @click.option("--coll", "-c", "collection", is_flag=True, help="Unpin the collection.")
144
+ @click.option(
145
+ "--all",
146
+ "all_settings",
147
+ is_flag=True,
148
+ help=(
149
+ "Unset every setting: shorthand for all the flags above, leaving every "
150
+ "one of them at its default."
151
+ ),
152
+ )
153
+ @click.pass_context
154
+ def unset_setting(
155
+ ctx: click.Context,
156
+ hints: bool,
157
+ prompt: bool,
158
+ url: bool,
159
+ project: bool,
160
+ collection: bool,
161
+ all_settings: bool,
162
+ ):
163
+ """Drop a setting back to its default.
164
+
165
+ The counterpart of 'tdk set': it removes what was stored for every setting
166
+ it is given, so the shipped default applies again. More than one can be
167
+ unset at once.
168
+
169
+ Examples:
170
+ tdk unset --hints
171
+ tdk unset --prompt
172
+ tdk unset --server
173
+ tdk unset --coll # unpin the collection only
174
+ tdk unset --proj # unpins the collection too
175
+ tdk unset --all # every setting
176
+ """
177
+ if all_settings:
178
+ hints = prompt = url = project = collection = True
179
+ if not (hints or prompt or url or project or collection):
180
+ raise click.UsageError(_NOTHING_TO_UNSET)
181
+ if hints:
182
+ _clear_enabled(ctx, OPTION_HINTS)
183
+ if prompt:
184
+ _clear_enabled(ctx, OPTION_PROMPT)
185
+ if url:
186
+ _unset_server(ctx)
187
+ if project or collection:
188
+ _unpin(ctx, project)
189
+ store_cli_options(ctx)
190
+
191
+
192
+ @cli_command
193
+ @click.command("settings")
194
+ @format_option
195
+ @click.pass_context
196
+ def settings(ctx: click.Context):
197
+ """Show the current settings.
198
+
199
+ The machine formats mirror what is stored in 'options.json'.
200
+ """
201
+ hints_enabled = cli_option_enabled(ctx, OPTION_HINTS)
202
+ prompt_enabled = cli_option_enabled(ctx, OPTION_PROMPT)
203
+ current_server = configured_server(ctx)
204
+ project = get_pin(ctx, PIN_PROJECT)
205
+ collection = get_pin(ctx, PIN_COLLECTION)
206
+
207
+ def _table():
208
+ click.echo(f"Hints: {_true_false(hints_enabled)}")
209
+ click.echo(f"Prompt: {_true_false(prompt_enabled)}")
210
+ click.echo(
211
+ f"Server: {current_server if current_server else '(none)'}"
212
+ )
213
+ click.echo(f"Pinned project: {project if project else '(none)'}")
214
+ click.echo(f"Pinned collection: {collection if collection else '(none)'}")
215
+
216
+ render(
217
+ ctx,
218
+ data={
219
+ OPTION_HINTS: _stored(hints_enabled),
220
+ OPTION_PROMPT: _stored(prompt_enabled),
221
+ OPTION_SERVER: current_server,
222
+ "pins": {PIN_PROJECT: project, PIN_COLLECTION: collection},
223
+ },
224
+ table=_table,
225
+ )
226
+
227
+
228
+ _TOGGLE_MESSAGES = {
229
+ OPTION_HINTS: (
230
+ "Hints enabled. You will now see hints in the CLI.",
231
+ "Hints disabled. You will no longer see hints in the CLI.",
232
+ ),
233
+ OPTION_PROMPT: (
234
+ "Prompting enabled. Commands will prompt for missing values.",
235
+ "Prompting disabled. Commands will fail instead of prompting for "
236
+ "missing values.",
237
+ ),
238
+ }
239
+
240
+ # Both on/off settings default to true, so unsetting one always lands on true.
241
+ _CLEARED_LABELS = {OPTION_HINTS: "Hints", OPTION_PROMPT: "Prompting"}
242
+
243
+
244
+ def _set_enabled(ctx: click.Context, option: str, enabled: bool):
245
+ set_cli_option_enabled(ctx, option, enabled)
246
+ click.echo(_TOGGLE_MESSAGES[option][0 if enabled else 1])
247
+
248
+
249
+ def _clear_enabled(ctx: click.Context, option: str):
250
+ label = _CLEARED_LABELS[option]
251
+ if get_current_cli_option(ctx, option) is None:
252
+ click.echo(f"{label} was already at its default (true).")
253
+ else:
254
+ clear_current_cli_option(ctx, option)
255
+ click.echo(f"{label} unset, back to its default (true).")
256
+
257
+
258
+ def _set_server(ctx: click.Context, url: str):
259
+ set_current_cli_option(ctx, OPTION_SERVER, url)
260
+ click.echo(f"Server set to {url}. 'tdk login' will use it without '--server'.")
261
+
262
+
263
+ def _unset_server(ctx: click.Context):
264
+ previous = configured_server(ctx)
265
+ clear_current_cli_option(ctx, OPTION_SERVER)
266
+ if previous:
267
+ click.echo(f"Server unset (was {previous}).")
268
+ else:
269
+ click.echo("No server was configured.")
270
+
271
+
272
+ def _pin(ctx: click.Context, project: str, collection: str):
273
+ # A collection only resolves relative to a pinned project -- one being set
274
+ # in this same command, or a pre-existing pin. Fail fast otherwise.
275
+ if collection and not (project or get_pin(ctx, PIN_PROJECT)):
276
+ raise click.ClickException(
277
+ "No project pinned. Pin a project first with 'tdk set --proj <name>' "
278
+ "before pinning a collection."
279
+ )
280
+ try:
281
+ if project:
282
+ previously_pinned = get_pin(ctx, PIN_PROJECT)
283
+ if previously_pinned and previously_pinned != project:
284
+ click.echo(f"Unpinning previously pinned project: {previously_pinned}")
285
+ set_pin(ctx, PIN_PROJECT, project)
286
+ click.echo(f"Pinning project: {project}")
287
+ # Switching to a different project orphans a collection pinned under
288
+ # the old one -- clear it, unless this command also sets a new
289
+ # collection (handled below). Re-pinning the same project keeps it.
290
+ if (
291
+ previously_pinned
292
+ and previously_pinned != project
293
+ and not collection
294
+ and get_pin(ctx, PIN_COLLECTION)
295
+ ):
296
+ orphan = get_pin(ctx, PIN_COLLECTION)
297
+ set_pin(ctx, PIN_COLLECTION, None)
298
+ click.echo(
299
+ "Also unpinning collection (it belonged to the previously "
300
+ f"pinned project): {orphan}"
301
+ )
302
+ if collection:
303
+ previously_pinned = get_pin(ctx, PIN_COLLECTION)
304
+ if previously_pinned and previously_pinned != collection:
305
+ click.echo(
306
+ f"Unpinning previously pinned collection: {previously_pinned}"
307
+ )
308
+ set_pin(ctx, PIN_COLLECTION, collection)
309
+ click.echo(f"Pinning collection: {collection}")
310
+ click.echo("Pins updated successfully")
311
+ except Exception as e:
312
+ hint_common_solutions(ctx, e)
313
+ raise click.ClickException(f"Failed to set pins: {e}")
314
+
315
+
316
+ def _unpin(ctx: click.Context, project: bool):
317
+ try:
318
+ # Clearing the project always cascades to the collection, since a
319
+ # collection only resolves under a project.
320
+ cleared = []
321
+ if project and get_pin(ctx, PIN_PROJECT):
322
+ cleared.append(f"project ({get_pin(ctx, PIN_PROJECT)})")
323
+ if get_pin(ctx, PIN_COLLECTION):
324
+ cleared.append(f"collection ({get_pin(ctx, PIN_COLLECTION)})")
325
+
326
+ if project:
327
+ set_pin(ctx, PIN_PROJECT, None)
328
+ set_pin(ctx, PIN_COLLECTION, None)
329
+
330
+ if cleared:
331
+ click.echo("Unpinned: " + ", ".join(cleared))
332
+ else:
333
+ click.echo("Nothing was pinned.")
334
+ except Exception as e:
335
+ hint_common_solutions(ctx, e)
336
+ raise click.ClickException(f"Failed to unset pins: {e}")
337
+
338
+
339
+ def _true_false(enabled: bool) -> str:
340
+ return _TRUE if enabled else _FALSE
341
+
342
+
343
+ def _stored(enabled: bool) -> str:
344
+ return ENABLED if enabled else DISABLED