Skip to content

docs: clarify username formats, ProjectLeader-as-group, and filter special-char behavior - #1854

Open
jacalata wants to merge 3 commits into
developmentfrom
jac/docs-stale-cleanup
Open

docs: clarify username formats, ProjectLeader-as-group, and filter special-char behavior#1854
jacalata wants to merge 3 commits into
developmentfrom
jac/docs-stale-cleanup

Conversation

@jacalata

@jacalata jacalata commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Closes #993, #1067, #1200.

Motivation

Three long-standing stale issues, all traceable to gaps in the same doc
region:

Behavior change

Docs only. No API change.

  • UserItem.name + users.add docstrings describe the required format per
    auth scheme: Cloud = email, local Server = username, AD-backed =
    SAMAccountName@FullyQualifiedDomain or UPN. Example split into Cloud +
    AD invocations.
  • projects.update_permissions example constructs a PermissionsRule
    with grantee=<group> and capability=ProjectLeader, plus a note that
    update_permissions fully replaces existing rules (call
    populate_permissions first if preserving).
  • Filter class + QuerySet.filter docstrings document the reserved
    delimiter characters and the *-wildcard workaround under the Equals
    operator, citing the server version requirement (Tableau Cloud May 2023
    or Tableau Server 2022.1.14) sourced from the public "Filtering and
    Sorting" REST API docs.

Test plan

  • test/test_user.py, test_user_model.py, test_project.py,
    test_project_model.py, test_filter.py: 89 passed
  • mypy clean

🤖 Generated with Claude Code

…ecial-char behavior

Bundles three long-standing docs gaps flagged in stale issues:

#993 - users.add example used a fake short username with no explanation
that `name` is the server auth identifier (email on Cloud, SAM@Domain on
AD-backed Server), not the person's display name. Rewrote the users.add
docstring intro to describe the required formats per auth scheme, split
the example into a Cloud invocation and an AD invocation, and added
matching guidance to UserItem.name.

#1067 - projects.update_permissions had no examples, so callers had no
guide for the common "assign group as Project Leader" case. Added an
example that shows constructing a PermissionsRule with grantee=<group>
and capability=ProjectLeader, plus a note that update_permissions is a
full replacement (call populate_permissions first if preserving
existing rules).

#1200 - the REST filter grammar treats ',', '&', ':', '[' and ']' as
delimiters and the server does not support escaping, so
`filter(name="T(L-F,SZ&V-MY)")` fails with 400065 for any name
containing those characters. Documented the constraint on the Filter
class docstring and on QuerySet.filter, along with the working
wildcard workaround (Equals with '*' substituted).

No behavior change. Docs only.

Closes #993, #1067, #1200.
@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown

Coverage

Coverage Report
FileStmtsMissCoverMissing
tableauserverclient
   __init__.py50100% 
   config.py150100% 
   datetime_helpers.py2511 96%
   exponential_backoff.py200100% 
   filesys_helpers.py310100% 
   namespace.py2633 88%
tableauserverclient/bin
   __init__.py20100% 
   _version.py358212212 41%
tableauserverclient/helpers
   __init__.py10100% 
   logging.py20100% 
   strings.py3111 97%
tableauserverclient/models
   __init__.py460100% 
   collection_item.py4177 83%
   column_item.py553232 42%
   connection_credentials.py351111 69%
   connection_item.py941414 85%
   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.py3101818 94%
   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.py1335195195 85%
   request_options.py38655 99%
   server.py1882323 88%
   sort.py60100% 
tableauserverclient/server/endpoint
   __init__.py350100% 
   auth_endpoint.py771111 86%
   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.py2122020 91%
   exceptions.py7766 92%
   extensions_endpoint.py310100% 
   favorites_endpoint.py942222 77%
   fileuploads_endpoint.py510100% 
   flow_runs_endpoint.py6299 85%
   flow_task_endpoint.py2122 90%
   flows_endpoint.py1985353 73%
   groups_endpoint.py12699 93%
   groupsets_endpoint.py7277 90%
   jobs_endpoint.py6799 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.py18388 96%
   views_endpoint.py15099 94%
   virtual_connections_endpoint.py1131010 91%
   webhooks_endpoint.py5499 83%
   workbooks_endpoint.py3382222 93%
TOTAL12007142388% 

The Equals-operator wildcard workaround for special characters requires
Tableau Cloud May 2023 or Tableau Server 2022.1.14 (per the REST API
"Filtering and Sorting" docs). Older servers reject `*` as a literal, so
readers on those need to know before copying the example.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

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 updates in-code documentation (docstrings) to clarify several commonly-misunderstood behaviors in the Tableau Server Client (TSC) Python library—specifically around user creation identifiers, project permission rules for Project Leaders, and REST filter limitations with reserved delimiter characters.

Changes:

  • Clarifies UserItem.name / users.add documentation to distinguish authentication username vs display name, with auth-scheme-specific examples.
  • Adds a concrete projects.update_permissions example for assigning a group as ProjectLeader, plus a warning that the call replaces the full permissions list.
  • Documents REST filter reserved delimiter characters and the * wildcard workaround in Filter and QuerySet.filter docstrings.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
tableauserverclient/server/query.py Adds QuerySet.filter docstring explaining shorthand operators and special-character caveat.
tableauserverclient/server/filter.py Adds detailed Filter docstring documenting delimiter characters and wildcard workaround/version constraints.
tableauserverclient/server/endpoint/users_endpoint.py Clarifies users.add docstring about required username formats and adds clearer examples.
tableauserverclient/server/endpoint/projects_endpoint.py Adds an example for assigning a group as Project Leader and notes replacement semantics.
tableauserverclient/models/user_item.py Clarifies UserItem.name parameter semantics and required formats per auth scheme.

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

Comment thread tableauserverclient/server/query.py Outdated
Comment on lines +191 to +194
Each keyword argument becomes one filter. Shorthand suffixes select
the operator (e.g. ``name__gt="A"`` -> operator ``GreaterThan``); a
bare keyword uses ``Equals``. See ``docs/filter-sort.md`` for the
supported suffixes.
jacalata added a commit that referenced this pull request Aug 17, 2026
Previous wording said wildcards, ranges, and operators are "NOT
supported" -- but I don't have live verification that `*` or `%` are
inert in a vf_ value. The public filtering docs describe only exact
match and OR-lists; behavior of other characters is undocumented, not
verifiably absent. Rephrase to say what we know (docs don't cover it,
TSC doesn't emit operator prefixes) and tell callers to verify against
their target server before relying on the outcome.

This is intentionally less prescriptive than the previous version.
The related open PR #1854 was flagged by the same fresh-eyes pass for
making an unverified `*`-as-wildcard claim in the opposite direction
-- both PRs should stay in "docs describe X; other behaviors are
untested" territory until we run the experiments.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three fresh-eyes findings:
- Replace Unicode em dashes (U+2014) in filter.py and users_endpoint.py
  docstrings with ASCII `--` or `;`, matching the repo's ASCII-only
  convention that other docstrings follow.
- query.py referenced docs/filter-sort.md, which lives on the gh-pages
  branch and does not exist in an installed package. Swap for the
  published URL so a `help()` reader can actually reach the doc.
- Soften the AD username claim in users_endpoint.py: a bare
  SAMAccountName's resolution depends on the AD configuration, so
  "typically will not resolve" was stated more strongly than the
  surrounding server-behavior guidance warranted.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Update docs and examples to properly show required fields for adding new users

2 participants