| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
The Tableau REST API supports a `refreshExtractTriggered="true"` attribute on subscription payloads that makes the subscription fire when its referenced schedule's extract refresh completes, rather than on the schedule's time trigger. On Tableau Cloud, this is the wire form of an "On Extract Refresh" subscription. TSC never exposed this attribute; users trying to create these subscriptions were passing `schedule_id=None` and hitting a confusing wire error deep in the endpoint layer. Changes: - `SubscriptionItem.on_extract_refresh(...)` classmethod factory constructs a subscription with an extract-refresh schedule id and the flag set. - `refresh_extract_triggered` exposed as a property with a docstring covering the two ways the server surprises callers (server rejects True with a non-extract schedule; server silently clears the flag when a schedule change is included in an update). - `Subscriptions.create()` and `.update()` now raise `ValueError` up front when `schedule_id` is missing, so the wire error becomes an actionable client-side message. - `create_req` emits `refreshExtractTriggered="true"` only when set; `update_req` emits both true and false so callers can turn the flag off on an existing subscription. - `_parse_element` reads the attribute back into the property; parse continues to accept inline-schedule responses (schedule_id=None). Tests cover: factory sets flag + schedule id; default false; create_req emit-when-set/omit-when-false; update_req always emits; parse round-trip for both true and missing; parse of inline-schedule responses; create() and update() reject missing schedule_id. Related to #1658. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sorry, something went wrong.
There was a problem hiding this comment.
Adds first-class support for Tableau REST API’s refreshExtractTriggered subscription attribute (Tableau Cloud “On Extract Refresh” subscriptions) by exposing it on SubscriptionItem, emitting/parsing it in XML requests/responses, and improving client-side validation/errors when schedule_id is missing.
Changes:
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| test/test_subscription.py | Adds tests for factory, defaults, XML emit/omit behavior, parsing, and create/update validation. |
| tableauserverclient/server/request_factory.py | Emits refreshExtractTriggered in create/update subscription request payloads. |
| tableauserverclient/server/endpoint/subscriptions_endpoint.py | Validates schedule_id presence for create/update and raises clearer ValueErrors. |
| tableauserverclient/models/subscription_item.py | Adds property + factory, documents behavior, and parses refreshExtractTriggered from responses. |
tableauserverclient/server/endpoint/subscriptions_endpoint.py:75
if not subscription_item.schedule_id:
# A subscription round-tripped from an inline-schedule response
# (Cloud/TOL) has schedule_id=None. Updating it in that state
# sends <schedule/> with no id and hits the same wire-layer error
# that create() guards against. See tableau/server-client-python#1658.
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Sorry, something went wrong.
- Docstring on `refresh_extract_triggered` now warns about the manual- build update() footgun: because every subscriptions.update() payload carries the attribute, a caller who builds a fresh SubscriptionItem locally, stamps _id, and updates will silently flip an existing on-extract-refresh subscription off. Fetch first. - Soften create()'s "schedule_id is required" error so someone who just forgot to set schedule_id on a time-based subscription doesn't get steered exclusively toward SubscriptionItem.on_extract_refresh(...); the factory is now mentioned as a conditional pointer. - __init__'s schedule_id parameter is now typed str | None, matching the real state: _parse_element sets it to None on inline-schedule responses. Drop the two `# type: ignore` markers in test/test_subscription.py that were papering over the earlier lie. - create_req asserts schedule_id non-None to satisfy mypy after the parameter widening; subscriptions.create() already guards this path before request emission. - Add samples/create_extract_refresh_subscription.py demonstrating the full flow: sign in, resolve view/workbook and user by name, pick an extract-refresh schedule from the schedules list, build the subscription via on_extract_refresh(), post it. Highest-leverage discoverability artifact for callers searching "on extract refresh". - CHANGELOG entry.
Three fresh-eyes findings: - Remove the "Subscriptions cannot use On Extract Refresh" entry. The REST API's refreshExtractTriggered attribute does support this, and TSC support is landing in #1861 (which closes the tracker #1658). The entry is about to be factually wrong on both counts. - Soften the intro: it promised "follow the appropriate issues" for every item, but the vf_-silently-dropped entry has no tracker filed. New wording says "where filed" so the doc doesn't overpromise. - Reword the daily-schedules note to describe behavior neutrally ("currently runs daily schedules hourly instead") rather than calling it a "bug", which reads punchy on a public docs page.
* docs: add Known server-side limitations section Add a new user-facing section to docs/api-ref.md that lists behaviors users may hit that are constrained by the Tableau Server REST API rather than by TSC. Each entry links its tracking issue and notes where the fix is expected to land. Cross-link the new section from the top-of-page note, and point at the `Server-Side Enhancement` label as the live tracker maintained by this repo. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs: drop internal work-item IDs and per-bullet fix-scope tag Public docs on gh-pages will be indexed, so remove the internal work-item numbers (W-...) from the Known server-side limitations section along with the paragraph that described what they were. Also strip the redundant per-bullet "Fix expected: server-side" tag: the section title already scopes the whole list to server-side gaps. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Drop On Extract Refresh entry, soften intro and daily-schedule wording Three fresh-eyes findings: - Remove the "Subscriptions cannot use On Extract Refresh" entry. The REST API's refreshExtractTriggered attribute does support this, and TSC support is landing in #1861 (which closes the tracker #1658). The entry is about to be factually wrong on both counts. - Soften the intro: it promised "follow the appropriate issues" for every item, but the vf_-silently-dropped entry has no tracker filed. New wording says "where filed" so the doc doesn't overpromise. - Reword the daily-schedules note to describe behavior neutrally ("currently runs daily schedules hourly instead") rather than calling it a "bug", which reads punchy on a public docs page. * Drop the vf_ exact-match limitation entry Opus-5 review found the entry's tracker link (#1431) points at a closed-not-planned issue; the underlying gap was filed with the Tableau REST API docs team internally and there's no realistic timeline for it being tracked back in the TSC repo. Rather than carry an untracked entry indefinitely, drop it. The behavior claim (vf_ is exact-match / OR-list only) is now covered by the expanded docstring on RequestOptions.vf() in #1840. --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Round of fixes for the sample-scripts refactor after fresh-eyes review. Blocker: publish_workbook.py reused `-u` for --thumbnails-user-id while _shared.py add_common_arguments already binds `-u` to --username, so argparse raised ArgumentError on module load and the script would not start. Renamed to `-U`. Real bugs: - _shared.py .env search now checks cwd, samples/, and repo root (in that order) so the docstring stops lying about "next to the sample or cwd." - resolve_credentials now gates input()/getpass on sys.stdin.isatty() as the docstring already promised, so piped/CI invocations no longer hang forever. - manage_subscriptions.py --attach-image switched to argparse.BooleanOptionalAction so users can actually pass --no-attach-image; the previous store_true+default=True made the flag a permanent True. - Header docstring in _shared.py no longer claims "no existing command line breaks" (which was false: -p migrated from --token-name to --password in an earlier commit). Documented the tabcmd-aligned short flags instead. - Corrected Python-version headers on login.py, list_jobs.py, manage_subscriptions.py, publish_workbook.py, refresh_tasks.py, move_workbook_sites.py, publish_datasource.py, and update_workbook_data_freshness_policy.py -- repo floor is 3.10 per pyproject.toml. - list_jobs._wait_for_job: reordered excepts so JobCancelledException (a subclass of JobFailedException) is caught first, otherwise cancelled jobs were reported as failed with the wrong exit code. - login.py sign-in banner now branches on JWTAuth as well, so JWT logins no longer print "Username: None". Header env-var list updated to include TABLEAU_JWT / TABLEAU_JWT_FILE. New JWT support: _shared.py add_common_arguments now exposes --jwt and --jwt-file, resolves TABLEAU_JWT / TABLEAU_JWT_FILE from env, reads a JWT file path into args.jwt during resolve_credentials, and returns TSC.JWTAuth from build_auth when a JWT is present. JWT takes priority over PAT and username/password. Extract-refresh subscription: manage_subscriptions.py create now accepts --on-extract-refresh, which calls SubscriptionItem.on_extract_refresh() to construct a subscription that fires when the referenced extract-refresh schedule completes (the flow introduced in #1861). Rebased this branch onto jac/subscription-refresh-extract-triggered so the flag lands on top of the new API without conflicts. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
| Back | FazBrowse Home | New Git URL |
Summary
Adds support for the REST API's refreshExtractTriggered="true" attribute on subscriptions -- the wire form of Tableau Cloud's "On Extract Refresh" subscriptions. When True, the subscription fires when the referenced schedule's extract refresh completes, rather than on the schedule's time trigger.
Closes #1658.
What changes
Compatibility note
Every subscriptions.update() payload now carries refreshExtractTriggered="true|false". Older servers that don't know the attribute should ignore unknown attrs on the <subscription> element per the schema's <xs:anyAttribute processContents="skip"/>; the attribute has been on the server since long before TSC's current minimum version.
Test plan
🤖 Generated with Claude Code