Fix #35: --nowait / --silent-progress on createsiteusers - #455
Draft
jacalata wants to merge 5 commits into
Draft
Conversation
…elease)
tabcmd Classic accepts --nowait and --silent-progress on createsiteusers;
tabcmd 2 was missing both flags. Adding them meaningfully requires more
than argparse: Classic sends the CSV as a single bulk-import job and
polls the server-side JobItem, while tabcmd 2 has been walking the CSV
row by row and calling users.add per user. With no server-side job to
poll, --nowait had nothing to skip.
This PR switches createsiteusers to server.users.bulk_add + a single
JobItem, and wires the two flags.
Behavior changes:
- Default: submit bulk_add, wait for the JobItem to complete via
server.jobs.wait_for_job, print a summary derived from the completed
job's status_notes (CountOfUsersAddedToSite / CountOfUsersSkipped /
CountOfUsersProcessed) plus any per-row error notes. Same shape as
Classic's default output.
- --nowait: submit bulk_add and return immediately. Job ID is printed
before return so callers can query it via a separate call.
- --silent-progress: still waits for the job, but suppresses the
status header, the queued-job line, and the per-row summary. Framework
logging (errors, debug) is unaffected.
- --complete / --no-complete: Classic used a ClientXML with_transaction
param that the REST endpoint doesn't expose, so we approximate with
client-side pre-flight validation:
- --complete (default): validate_file_for_import(strict=True), any
malformed row aborts the whole import before submission.
- --no-complete: validate leniently, submit whatever parses.
Doesn't cover server-side row failures mid-import; those fall through
to job.status_notes on the completed job.
Flag spelling: Classic uses --nowait (one word). The existing
set_no_wait_option helper defined --no-wait but had zero callers, so
switched the spelling to Classic's without a compatibility alias.
Depends on TSC >= (next release), which will ship JobItem.status_notes
(tableau/server-client-python#1852, merged). Draft while awaiting a
tagged TSC release + tabcmd's TSC pin bump.
Fixes #35.
TSC top-level doesn't re-export JobFailedException; import directly from tableauserverclient.server.endpoint.exceptions. Fixes the mypy attr-defined error in CI.
The status_notes fallback previously used getattr(..., None) or [] which meant an older TSC would print added=0, skipped=0, processed=len(input) with no indication anything was wrong. Detect the attribute missing and exit with a message pointing at the pinned TSC version. --continue-if-exists is a global flag used across the create-* commands to downgrade 409 conflicts to INFO. bulk_add is inherently tolerant of duplicate users (they get counted under CountOfUsersSkipped) so the flag is a no-op here. Keep the flag on the parser for consistency, log the no-op at DEBUG, and cover with a test so a future refactor doesn't accidentally rely on it. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
test_continue_if_exists_is_a_noop_documented_in_debug just re-ran the default happy path with the flag set. bulk_add is called and wait_for_job is called either way, so this asserts nothing that the base test doesn't. The behavioral comment lives on the code path in create_site_users.py already. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #35.
Motivation
tabcmd Classic accepts
--nowaitand--silent-progressoncreatesiteusers; tabcmd 2 was missing both. Wiring them meaningfullyrequires more than argparse: Classic sends the CSV as a single
bulk-import job and polls the server-side
JobItem, while tabcmd 2 waswalking the CSV row by row and calling
users.addper user. With noserver-side job to poll,
--nowaithad nothing to skip. This PRswitches
createsiteuserstoserver.users.bulk_add+ a singleJobItemand wires both flags.Behavior change
For users:
bulk_add, wait for theJobItemviaserver.jobs.wait_for_job, print a summary fromstatus_notes(
CountOfUsersAddedToSite,CountOfUsersSkipped,CountOfUsersProcessed) plus per-row error notes. Same shape asClassic's default output.
--nowait:bulk_addthen return immediately. Job ID is printedbefore return so callers can query it later.
--silent-progress: still waits for the job but suppresses thestatus header, queued-job line, and per-row summary.
--complete/--no-complete: approximated via client-sidepre-flight validation (
validate_file_for_import(strict=...)).Classic used a ClientXML
with_transactionparam the REST endpointdoesn't expose, so under
--complete(default) malformed rows abortbefore submission; under
--no-completewe validate leniently.Server-side row failures mid-import still surface via
job.status_notes.--continue-if-exists: no-op on this command (bulk_add isinherently tolerant of duplicate users -- they get counted under
CountOfUsersSkipped). Kept on the parser for consistency withsibling create commands; logged at DEBUG.
Flag spelling: Classic uses
--nowait(one word). The existingset_no_wait_optionhelper defined--no-waitbut had zero callers,so rewrote to
--nowaitwith no compatibility alias.Older-TSC safety: if the pinned
tableauserverclientpredatesJobItem.status_noteswe can't produce a truthful summary. Exit withan error message pointing at the pinned TSC version rather than silently
print zeros that look like success.
Draft: depends on TSC release
Depends on
tableauserverclient>= (next release), which shipsJobItem.status_notesfrom tableau/server-client-python#1852 (merged).Draft while awaiting a tagged TSC release + tabcmd's TSC pin bump.
Test plan
--nowait,--silent-progress, both togetherbulk_add+wait_for_job;--nowaitskipswait_for_job;--silent-progressstill waits;both flags coexist; older-TSC without status_notes exits with error
🤖 Generated with Claude Code