GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Proposed: Remove pre-8.3 XML namespace fallback by jacalata · Pull Request #1863 · tableau/server-client-python

Conversation

@jacalata

@jacalata jacalata commented Aug 16, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

Summary

Removes the runtime XML namespace detection that let TSC accept responses from Tableau Server versions predating 8.3 (2013, http://tableausoftware.com/api). The library's minimum_supported_server_version has been 2.3 for years (Tableau Server 10.0, 2016), so the detection has been unreachable for a decade.

Fixes #1046. Also makes #1866 moot: its application/xml vs text/xml guard in Endpoint._make_request is deleted here along with the detect() call.

What changes

Removed:

  • tableauserverclient/namespace.py (the whole module) and the symbols it exported: Namespace, UnknownNamespaceError, OLD_NAMESPACE, NEW_NAMESPACE, NAMESPACE_RE.
  • Server._namespace and the per-response .detect(...) call in Endpoint._make_request and both sign-in paths in Auth.

Kept:

  • Public TSC.DEFAULT_NAMESPACE re-export, with the same string value. It is a literal in __init__.py because importing it from server.server is circular; test/test_namespace.py pins it to server.server.NAMESPACE.
  • Server.namespace property, which returns a fresh {"t": NAMESPACE} dict on each call, the same shape callers pass to ElementTree's namespaces= kwarg.

Compatibility

Breaking for callers who import directly from tableauserverclient.namespace (Namespace, UnknownNamespaceError, OLD_NAMESPACE, NEW_NAMESPACE, NAMESPACE_RE) rather than the documented TSC.DEFAULT_NAMESPACE. The module was internal in every sense except being top-level, so this is an outright removal with no deprecation shim. CHANGELOG.md now points to GitHub Releases, so the release notes should carry this line.

Why now

Discussion in #1039 (2022) already noted the fallback was safe to drop; the issue has been open since. Nothing in the diff is complicated; the code is simply dead.

Written with Claude Code

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@jacalata @claude
refactor: remove pre-8.3 XML namespace fallback (#1046)
fcd07ca
The `Namespace` class detected `http://tableausoftware.com/api` (the pre-8.3
namespace) at runtime on every XML response and let the parser silently switch
namespaces if it saw the old one. That behavior has been unreachable for years:
the library's `minimum_supported_server_version` is 2.3, which corresponds to
Tableau Server 10.0 -- shipped in 2016, three years after the namespace changed.
Every server TSC has ever admitted uses `http://tableau.com/api`.

Removes:
- `tableauserverclient/namespace.py` (the module) and everything it exported:
  `Namespace`, `UnknownNamespaceError`, `OLD_NAMESPACE`, `NEW_NAMESPACE`,
  `NAMESPACE_RE`.
- `Server._namespace` instance and the per-response `.detect(...)` call in
  `Endpoint._make_request` and both sign-in paths in `Auth`.

Keeps:
- The public `TSC.DEFAULT_NAMESPACE` re-export -- now sourced from
  `tableauserverclient.server.server.NAMESPACE`, which is the canonical
  constant. Same string value.
- `Server.namespace` property -- still returns the `{"t": NAMESPACE}` dict
  callers pass to ElementTree's `namespaces=` kwarg. Same shape.

Callers who imported directly from `tableauserverclient.namespace` (rather
than `TSC.DEFAULT_NAMESPACE`) will break; the CHANGELOG entry calls this out.

Fixes #1046.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
@github-actions

github-actions Bot commented Aug 16, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown

Coverage

Coverage Report
FileStmtsMissCoverMissing
tableauserverclient
   __init__.py50100% 
   config.py150100% 
   datetime_helpers.py2511 96%
   exponential_backoff.py200100% 
   filesys_helpers.py310100% 
tableauserverclient/bin
   __init__.py20100% 
   _version.py358212212 41%
tableauserverclient/helpers
   __init__.py10100% 
   logging.py20100% 
   strings.py3111 97%
tableauserverclient/models
   __init__.py470100% 
   auth_federation_item.py8799 90%
   collection_item.py4177 83%
   column_item.py553232 42%
   connection_credentials.py351111 69%
   connection_item.py1131313 88%
   custom_view_item.py1442121 85%
   data_acceleration_report_item.py5411 98%
   data_alert_item.py15844 97%
   data_freshness_policy_item.py1551515 90%
   database_item.py2073636 83%
   datasource_item.py3001212 96%
   dqw_item.py10455 95%
   exceptions.py40100% 
   extensions_item.py13244 97%
   extract_item.py4444 91%
   favorites_item.py6988 88%
   fileupload_item.py190100% 
   flow_item.py1491010 93%
   flow_run_item.py710100% 
   group_item.py8966 93%
   groupset_item.py4977 86%
   interval_item.py1823232 82%
   job_item.py1921010 95%
   linked_tasks_item.py7911 99%
   location_item.py2922 93%
   metric_item.py1291313 90%
   oidc_item.py6333 95%
   pagination_item.py3411 97%
   permissions_item.py1111212 89%
   project_item.py2073131 85%
   property_decorators.py1001818 82%
   reference_item.py2622 92%
   revision_item.py5911 98%
   schedule_item.py20966 97%
   server_info_item.py3777 81%
   site_item.py6361313 98%
   subscription_item.py10122 98%
   table_item.py1191818 85%
   tableau_auth.py612525 59%
   tableau_types.py2711 96%
   tag_item.py150100% 
   target.py60100% 
   task_item.py5622 96%
   user_item.py3381717 95%
   view_item.py2201616 93%
   virtual_connection_item.py6488 88%
   webhook_item.py6911 99%
   workbook_item.py3621616 96%
tableauserverclient/server
   __init__.py90100% 
   exceptions.py40100% 
   filter.py2911 97%
   pager.py3311 97%
   query.py1431515 90%
   request_factory.py1366194194 86%
   request_options.py38655 99%
   server.py2502525 90%
   sort.py60100% 
tableauserverclient/server/endpoint
   __init__.py360100% 
   auth_endpoint.py721010 86%
   auth_federation_endpoint.py800100% 
   custom_views_endpoint.py1521212 92%
   data_acceleration_report_endpoint.py210100% 
   data_alert_endpoint.py942323 76%
   databases_endpoint.py1113030 73%
   datasources_endpoint.py3233333 90%
   default_permissions_endpoint.py4433 93%
   dqw_endpoint.py451616 64%
   endpoint.py2582424 91%
   exceptions.py7966 92%
   extensions_endpoint.py310100% 
   favorites_endpoint.py942222 77%
   fileuploads_endpoint.py510100% 
   flow_runs_endpoint.py6299 85%
   flow_task_endpoint.py2122 90%
   flows_endpoint.py1984747 76%
   groups_endpoint.py12699 93%
   groupsets_endpoint.py7277 90%
   jobs_endpoint.py6899 87%
   linked_tasks_endpoint.py370100% 
   metadata_endpoint.py881414 84%
   metrics_endpoint.py5566 89%
   oidc_endpoint.py4211 98%
   permissions_endpoint.py4433 93%
   projects_endpoint.py1782424 87%
   resource_tagger.py1273535 72%
   schedules_endpoint.py1191111 91%
   server_info_endpoint.py361010 72%
   sites_endpoint.py1302727 79%
   subscriptions_endpoint.py561414 75%
   tables_endpoint.py1103636 67%
   tasks_endpoint.py6366 90%
   users_endpoint.py17077 96%
   views_endpoint.py15099 94%
   virtual_connections_endpoint.py1131010 91%
   webhooks_endpoint.py5499 83%
   workbooks_endpoint.py3382222 93%
TOTAL12321142488% 
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@jacalata jacalata mentioned this pull request Aug 17, 2026
Endpoint._make_request namespace detection guard misses text/xml responses #1866
Closed
@jacalata
jacalata requested a lite review from Copilot August 17, 2026 20:03
Copilot started reviewing on behalf of jacalata August 17, 2026 20:04
View session
Copilot AI reviewed Aug 17, 2026
View reviewed changes

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR removes runtime XML namespace detection that allowed parsing legacy (pre-Tableau Server 8.3) REST API XML responses, standardizing the client on the modern http://tableau.com/api namespace in line with the library’s long-standing minimum supported server/API versions.

Changes:

  • Removed the tableauserverclient.namespace module and eliminated per-response namespace detection calls.
  • Centralized the namespace constant in server.server and updated TSC.DEFAULT_NAMESPACE to keep the public re-export working.
  • Updated server/endpoint code paths to always use the fixed namespace map.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tableauserverclient/server/server.py Removes per-instance namespace detector and introduces fixed namespace constants/map.
tableauserverclient/server/endpoint/endpoint.py Removes the XML-response namespace detection hook in _make_request.
tableauserverclient/server/endpoint/auth_endpoint.py Removes namespace detection during sign-in and site switching flows.
tableauserverclient/namespace.py Deletes the legacy namespace detection module and exported symbols.
tableauserverclient/init.py Updates DEFAULT_NAMESPACE re-export to come from the new namespace source.
CHANGELOG.md Documents the breaking removal of legacy namespace fallback and module exports.
Suppressed comments (2)

tableauserverclient/server/endpoint/auth_endpoint.py:159

  • With namespace auto-detection removed, a legacy-namespace (or otherwise unexpected) XML response can make find(...).get(...) raise AttributeError. Adding an explicit check and raising ServerResponseError produces a clearer, user-facing failure mode for unsupported namespaces/servers.
        parsed_response = fromstring(server_response.content)
        site_id = parsed_response.find(".//t:site", namespaces=self.parent_srv.namespace).get("id", None)
        site_url = parsed_response.find(".//t:site", namespaces=self.parent_srv.namespace).get("contentUrl", None)

tableauserverclient/server/endpoint/auth_endpoint.py:86

  • With namespace auto-detection removed, a legacy-namespace (or otherwise unexpected) XML response will make find(...).get(...) raise an AttributeError, which is hard to diagnose. It’s better to explicitly check that the expected elements are present and raise ServerResponseError with a message that points to a likely namespace / server-version mismatch.

This issue also appears on line 157 of the same file.

        parsed_response = fromstring(server_response.content)
        site_id = parsed_response.find(".//t:site", namespaces=self.parent_srv.namespace).get("id", None)
        site_url = parsed_response.find(".//t:site", namespaces=self.parent_srv.namespace).get("contentUrl", None)

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread tableauserverclient/server/server.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread tableauserverclient/__init__.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

@jacalata
Return a fresh dict from Server.namespace so callers cannot pollute s…
ef3ef1f
…hared state

Copilot flagged that Server.namespace returned the module-level
_NAMESPACE_MAP directly, so a caller mutating the returned dict would
have polluted every other Server instance in the process. Old namespace-
handling code returned a per-instance dict, so no cross-instance
pollution was possible. Wrap in dict(...) to restore that behavior.
jacalata added a commit that referenced this pull request Aug 20, 2026
@jacalata
Followup polish on the redirect walker landed in #1848
65df951
Two adjustments from a post-merge fresh-eyes pass:

- endpoint.py: the http -> https address-promotion match now compares
  hostnames case-insensitively (RFC 3986) and normalizes http://host
  vs http://host:80 so a same-host promotion doesn't silently drop.
  Split into two comparisons: current-vs-next is hostname-only
  (schemes differ so default port differs, comparing raw netloc
  would spuriously mismatch); old-address-vs-current is same-scheme
  and uses (hostname, effective port) so explicit-vs-implicit port
  compares equal. Expanded the auth-material comment to acknowledge
  that sign_in itself carries raw credentials in the POST body, not
  only the issued token on subsequent calls.

- test_redirect_handling.py: added a docstring on
  test_all_supported_redirect_codes_preserve_post_body naming the
  RFC 7231 6.4.4 deviation on 303 -- if a future refactor
  "helpfully" converts 303 to GET, the parametrized test fails
  with a clear intent statement.

Also considered a sign_in namespace-detect hedge for pre-8.3
Tableau responses (Copilot flagged this on #1848); dropped as
theoretical because TSC's minimum_supported_server_version = 2.3
(Tableau 10.0, 2016) is eight years past the namespace change,
and #1863 removes the whole subsystem anyway.
@jacalata jacalata mentioned this pull request Aug 20, 2026
Redirect walker followups: hostname/port match + RFC 303 test docstring #1868
Open
2 tasks done
@jacalata jacalata changed the title Remove pre-8.3 XML namespace fallback Proposed: Remove pre-8.3 XML namespace fallback Aug 20, 2026
jacalata added 3 commits August 19, 2026 22:22
@jacalata
Merge remote-tracking branch 'origin/development' into jac/1046-remov…
eafeece
…e-old-namespace

# Conflicts:
#	tableauserverclient/server/endpoint/auth_endpoint.py
@jacalata
Inline DEFAULT_NAMESPACE literal to avoid top-level server.py import
26bcfbb
Cosmetic import-graph cleanup on top of #1863's move of `NAMESPACE`
from `namespace.py` into `server/server.py`. Before this change,
`tableauserverclient/__init__.py:2` did `from tableauserverclient.
server.server import NAMESPACE`, which forces `server.server` (and
its transitive endpoint tree) to load just to read a string
constant.

Copilot flagged the circular-import path this creates: `server.
server` -> `server.endpoint.endpoint` -> `from tableauserverclient
import ...` -> `__init__` -> `server.server`. Python resolves the
chain today because the reentrant lookups pull submodules whose
own load doesn't back-reference the partially-initialized parent,
but the shape is fragile and adding a new top-level import to
`__init__.py` before line 2 could easily break it.

Replaced the import with the string literal. Kept in sync with
the `NAMESPACE` constant in `server/server.py`. Also removes one
of the two entry points into `server.server` at package load,
though everything else in `__init__.py` still transitively pulls
the endpoint tree via the models block below, so no real startup
savings -- this is defensive, not a perf fix.
@jacalata
Merge origin/development into jac/1046-remove-old-namespace
575f6ab
CHANGELOG.md: development now points to the GitHub Releases page, so the
changelog entry for this change is dropped (the breaking-change note moves
to the PR description).
tableauserverclient/namespace.py: deletion kept; development only added
docstrings to the removed module.

Add test/test_namespace.py pinning TSC.DEFAULT_NAMESPACE to server.NAMESPACE
and checking Server.namespace returns an independent copy.

Written with Claude Code
@jacalata
jacalata marked this pull request as ready for review November 10, 2026 23:02
Copilot AI lite review requested due to automatic review settings November 10, 2026 23:02
Copilot started reviewing on behalf of jacalata November 10, 2026 23:03
View session
Copilot AI reviewed Nov 10, 2026
View reviewed changes

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

No active review issues are identified, and the change consistently removes obsolete namespace detection while preserving the documented public interfaces and defensive mapping behavior.

No open issues 🎉

2 resolved since last review
  • High severity Importing NAMESPACE from tableauserverclient.server.server at module import time introduces a…
  • Medium severity Server.namespace currently returns a module-level dict (_NAMESPACE_MAP). Because dicts are…

Review effort: Lite

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

Copilot code review Copilot
Copilot review effort
Applies to this pull request for everyone.Learn more about Copilot code review.
Copilot left review comments

At least 1 approving review is required to merge this pull request.

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Stop supporting old namespaces

Uh oh!

There was an error while loading. Please reload this page.

2 participants

@jacalata
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.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.