From db6b9a4a7dc9590cfa68675cb7ba13cb245d0eff Mon Sep 17 00:00:00 2001 From: Jac Date: Fri, 19 Jun 2026 23:43:49 -0700 Subject: [PATCH 1/7] Create .readthedocs.yaml for documentation setup Add Read the Docs configuration file for documentation build --- .readthedocs.yaml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 .readthedocs.yaml diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 000000000..575f578ef --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,23 @@ +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Set the OS, Python version, and other tools you might need +build: + os: ubuntu-24.04 + tools: + python: "3.13" + +# Build documentation in the "docs/" directory with Sphinx +sphinx: + configuration: docs/conf.py + +# Optionally, but recommended, +# declare the Python requirements required to build your documentation +# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html +# python: +# install: +# - requirements: docs/requirements.txt + From b021986bade20e486b4a761165c22b5acc889f81 Mon Sep 17 00:00:00 2001 From: Jac Date: Fri, 19 Jun 2026 23:49:38 -0700 Subject: [PATCH 2/7] Create Sphinx configuration file for documentation Added configuration settings for Sphinx documentation. Direct copy from example conf file. --- docs/conf.py | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 docs/conf.py diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 000000000..8e7f9a999 --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,50 @@ +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + + +# -- Project information ----------------------------------------------------- + +project = "Basic Sphinx Example Project" +copyright = "2022, Read the Docs core team" +author = "Read the Docs core team" + + +# -- General configuration --------------------------------------------------- +# -- General configuration + +extensions = [ + "sphinx.ext.duration", + "sphinx.ext.doctest", + "sphinx.ext.autodoc", + "sphinx.ext.autosummary", + "sphinx.ext.intersphinx", +] + +intersphinx_mapping = { + "rtd": ("https://docs.readthedocs.io/en/stable/", None), + "python": ("https://docs.python.org/3/", None), + "sphinx": ("https://www.sphinx-doc.org/en/master/", None), +} +intersphinx_disabled_domains = ["std"] + +templates_path = ["_templates"] + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = "sphinx_rtd_theme" + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ["_static"] From a195f86e95575ea38f9c22a5d254acb6445f6554 Mon Sep 17 00:00:00 2001 From: Jac Date: Fri, 19 Jun 2026 23:58:23 -0700 Subject: [PATCH 3/7] Load project details from pyproject.toml Updated project information to load from pyproject.toml. --- docs/conf.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 8e7f9a999..301922d18 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -6,11 +6,23 @@ # -- Project information ----------------------------------------------------- +# Source - https://stackoverflow.com/a/75396624 +# Posted by Jan, modified by community. See post 'Timeline' for change history +# Retrieved 2026-06-19, License - CC BY-SA 4.0 -project = "Basic Sphinx Example Project" -copyright = "2022, Read the Docs core team" -author = "Read the Docs core team" +# conf.py +import tomli +with open("../../pyproject.toml", "rb") as f: + toml = tomli.load(f) + +# -- Project information ----------------------------------------------------- + +pyproject = toml["tool"]["setuptools"] + +project = pyproject["name"] +version = pyproject["version"] +release = pyproject["version"] # -- General configuration --------------------------------------------------- # -- General configuration From ed8b75fd2ca102b5edbc8e5365346345064fcefd Mon Sep 17 00:00:00 2001 From: Jac Fitzgerald Date: Sat, 20 Jun 2026 00:22:12 -0700 Subject: [PATCH 4/7] docs: set up Sphinx with working ReadTheDocs config - Add docs optional-dependencies group (sphinx, tomli) to pyproject.toml - Wire up .readthedocs.yaml to install .[docs] extra - Fix conf.py: correct pyproject.toml path, use importlib.metadata for version, switch to alabaster theme, use tomllib/tomli compat import - Add minimal docs/index.rst - Fix RST docstring errors in connection_item, site_item, job_item, task_item that caused Sphinx build warnings/errors Co-Authored-By: Claude Sonnet 4.6 --- .readthedocs.yaml | 10 +++++--- docs/conf.py | 25 +++++++++++-------- docs/index.rst | 9 +++++++ pyproject.toml | 1 + tableauserverclient/models/connection_item.py | 11 +------- tableauserverclient/models/job_item.py | 2 +- tableauserverclient/models/site_item.py | 7 ++++-- tableauserverclient/models/task_item.py | 2 +- 8 files changed, 39 insertions(+), 28 deletions(-) create mode 100644 docs/index.rst diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 575f578ef..96209fd5a 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -17,7 +17,9 @@ sphinx: # Optionally, but recommended, # declare the Python requirements required to build your documentation # See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html -# python: -# install: -# - requirements: docs/requirements.txt - +python: + install: + - method: pip + path: . + extra_requirements: + - docs diff --git a/docs/conf.py b/docs/conf.py index 301922d18..929b00be8 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -12,17 +12,22 @@ # conf.py -import tomli -with open("../../pyproject.toml", "rb") as f: - toml = tomli.load(f) +try: + import tomllib +except ImportError: + import tomli as tomllib -# -- Project information ----------------------------------------------------- +from pathlib import Path +import importlib.metadata + +with open(Path(__file__).parent.parent / "pyproject.toml", "rb") as f: + toml = tomllib.load(f) -pyproject = toml["tool"]["setuptools"] +# -- Project information ----------------------------------------------------- -project = pyproject["name"] -version = pyproject["version"] -release = pyproject["version"] +project = toml["project"]["name"] +release = importlib.metadata.version(project) +version = ".".join(release.split(".")[:2]) # -- General configuration --------------------------------------------------- # -- General configuration @@ -54,9 +59,9 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # -html_theme = "sphinx_rtd_theme" +html_theme = "alabaster" # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ["_static"] +html_static_path = [] diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 000000000..5ae5061f0 --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,9 @@ +tableauserverclient +=================== + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + +.. automodule:: tableauserverclient + :members: diff --git a/pyproject.toml b/pyproject.toml index e5a330c39..a0d9a9f11 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,6 +35,7 @@ repository = "https://github.com/tableau/server-client-python" [project.optional-dependencies] test = ["black==26.5.1", "build", "mypy==2.3.0", "pytest>=7.0", "pytest-cov", "pytest-subtests", "pytest-xdist", "requests-mock>=1.0,<2.0", "types-requests>=2.32.4.20250913"] +docs = ["sphinx", "tomli"] [tool.setuptools.package-data] # Only include data for tableauserverclient, not for samples, test, docs diff --git a/tableauserverclient/models/connection_item.py b/tableauserverclient/models/connection_item.py index fa4b8cf9f..0dbadeda6 100644 --- a/tableauserverclient/models/connection_item.py +++ b/tableauserverclient/models/connection_item.py @@ -150,16 +150,7 @@ def from_response(cls, resp, ns) -> list["ConnectionItem"]: @classmethod def from_xml_element(cls, parsed_response, ns) -> list["ConnectionItem"]: - """ - - - - - - - - - """ + """Parse connection items from an XML ```` element.""" all_connection_items: list["ConnectionItem"] = list() all_connection_xml = parsed_response.findall(".//t:connection", namespaces=ns) diff --git a/tableauserverclient/models/job_item.py b/tableauserverclient/models/job_item.py index f684c22d4..82aa8e080 100644 --- a/tableauserverclient/models/job_item.py +++ b/tableauserverclient/models/job_item.py @@ -27,7 +27,7 @@ class JobItem: Parameters ---------- - id_ : str + id : str The identifier of the job. job_type : str diff --git a/tableauserverclient/models/site_item.py b/tableauserverclient/models/site_item.py index 382ca63db..8cea6a7ab 100644 --- a/tableauserverclient/models/site_item.py +++ b/tableauserverclient/models/site_item.py @@ -52,10 +52,13 @@ class SiteItem: cause an error. tier_explorer_capacity: int + (Optional) The maximum number of licenses for users with the Explorer role allowed on a site. + tier_creator_capacity: int + (Optional) The maximum number of licenses for users with the Creator role allowed on a site. + tier_viewer_capacity: int - (Optional) The maximum number of licenses for users with the Creator, - Explorer, or Viewer role, respectively, allowed on a site. + (Optional) The maximum number of licenses for users with the Viewer role allowed on a site. storage_quota: int (Optional) Specifies the maximum amount of space for the new site, in diff --git a/tableauserverclient/models/task_item.py b/tableauserverclient/models/task_item.py index b343f3c22..a8a672a4a 100644 --- a/tableauserverclient/models/task_item.py +++ b/tableauserverclient/models/task_item.py @@ -13,7 +13,7 @@ class TaskItem: Parameters ---------- - id_ : str + id : str The ID of the task. task_type : str From 8cebc5ec2eb50403a5fe8caaaf505852900985a7 Mon Sep 17 00:00:00 2001 From: Jac Fitzgerald Date: Sat, 20 Jun 2026 00:37:42 -0700 Subject: [PATCH 5/7] change theme --- docs/conf.py | 3 ++- pyproject.toml | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 929b00be8..0f8e53f3c 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -38,6 +38,7 @@ "sphinx.ext.autodoc", "sphinx.ext.autosummary", "sphinx.ext.intersphinx", + "sphinx.ext.napoleon", ] intersphinx_mapping = { @@ -59,7 +60,7 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # -html_theme = "alabaster" +html_theme = "furo" # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, diff --git a/pyproject.toml b/pyproject.toml index a0d9a9f11..1128e30a4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,7 +35,7 @@ repository = "https://github.com/tableau/server-client-python" [project.optional-dependencies] test = ["black==26.5.1", "build", "mypy==2.3.0", "pytest>=7.0", "pytest-cov", "pytest-subtests", "pytest-xdist", "requests-mock>=1.0,<2.0", "types-requests>=2.32.4.20250913"] -docs = ["sphinx", "tomli"] +docs = ["sphinx", "tomli", "furo"] [tool.setuptools.package-data] # Only include data for tableauserverclient, not for samples, test, docs From 3cf02f6877e8fc3a685af1ba98b6de7af735f91b Mon Sep 17 00:00:00 2001 From: Jac Fitzgerald Date: Sat, 20 Jun 2026 10:48:47 -0700 Subject: [PATCH 6/7] ci: add workflow to build Sphinx docs and PR to gh-pages On push to master, builds Sphinx HTML and opens a PR from docs-update into gh-pages so the generated API reference can be reviewed before going live. Co-Authored-By: Claude Sonnet 4.6 --- .github/workflows/docs.yml | 46 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 .github/workflows/docs.yml diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 000000000..16c8d1b9c --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,46 @@ +name: Build and publish docs + +on: + push: + branches: [master] + +permissions: + contents: write + pull-requests: write + +jobs: + build-and-pr: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install docs dependencies + run: pip install -e ".[docs]" + + - name: Build Sphinx docs + run: sphinx-build -b html docs sphinx_build + + - name: Checkout gh-pages + uses: actions/checkout@v4 + with: + ref: gh-pages + path: gh-pages + + - name: Copy Sphinx output into gh-pages/sphinx + run: | + rm -rf gh-pages/sphinx + cp -r sphinx_build gh-pages/sphinx + + - name: Create PR to gh-pages + uses: peter-evans/create-pull-request@v6 + with: + path: gh-pages + branch: docs-update + base: gh-pages + title: "docs: update generated API reference" + body: "Automated update of Sphinx-generated API reference from master." + commit-message: "docs: regenerate Sphinx API reference" From 939ad9d4b3b0531d98ca126bbf1e253d546f522e Mon Sep 17 00:00:00 2001 From: Jac Fitzgerald Date: Tue, 28 Jul 2026 22:35:06 -0700 Subject: [PATCH 7/7] docs: address adversarial review findings on Sphinx/RTD pipeline MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Four cleanups on the docs branch surfaced by an adversarial review: - Revert id_ -> id docstring renames in JobItem and TaskItem. The constructors take `id_` (trailing underscore because `id` shadows the builtin); the docstring should describe the actual parameter name. The original rename was cosmetic and made the docstring actively misleading — users copying the docstring's kwarg would get a TypeError. - Add :imported-members: to docs/index.rst. Without it, the top-level automodule directive only documents symbols defined in tableauserverclient/__init__.py itself (which is 99% re-exports), so the generated API reference was nearly empty. With this, all re-exported classes render. - Pin [docs] extras. Was `sphinx`, `tomli`, `furo` — unpinned. Now `sphinx>=7,<9`, `furo>=2024,<2027`, `tomli; python_version < '3.11'`. A future Sphinx major bump can silently break the RTD reproducible build otherwise. `tomli` narrowed to just the Python 3.10 build path; 3.11+ has stdlib tomllib. - Workflow changes: - Add `concurrency: docs-publish` so overlapping runs don't rewrite docs-update mid-flight. - Set `delete-branch: true` on peter-evans/create-pull-request so stale docs-update branches don't accumulate and force-updates don't strand review comments. - Set `fetch-depth: 0` on the gh-pages checkout so create-pull-request can detect no-op diffs correctly. - Remove the templates_path = ["_templates"] config in docs/conf.py. The referenced directory doesn't ship, so Sphinx emits a warning on every build. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/docs.yml | 12 ++++++++++++ docs/conf.py | 2 -- docs/index.rst | 1 + pyproject.toml | 2 +- tableauserverclient/models/job_item.py | 2 +- tableauserverclient/models/task_item.py | 2 +- 6 files changed, 16 insertions(+), 5 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 16c8d1b9c..7c0da30a1 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -8,6 +8,12 @@ permissions: contents: write pull-requests: write +# Serialize docs regen runs so a new push doesn't rewrite the docs-update +# branch mid-flight for a prior run that hasn't finished opening its PR. +concurrency: + group: docs-publish + cancel-in-progress: false + jobs: build-and-pr: runs-on: ubuntu-latest @@ -29,18 +35,24 @@ jobs: with: ref: gh-pages path: gh-pages + fetch-depth: 0 - name: Copy Sphinx output into gh-pages/sphinx run: | rm -rf gh-pages/sphinx cp -r sphinx_build gh-pages/sphinx + # delete-branch: true removes the docs-update branch after its PR is + # merged/closed. Without it, an unmerged prior PR's branch gets + # force-updated on the next run and any review comments on it are + # stranded. - name: Create PR to gh-pages uses: peter-evans/create-pull-request@v6 with: path: gh-pages branch: docs-update base: gh-pages + delete-branch: true title: "docs: update generated API reference" body: "Automated update of Sphinx-generated API reference from master." commit-message: "docs: regenerate Sphinx API reference" diff --git a/docs/conf.py b/docs/conf.py index 0f8e53f3c..f9fcbf1bc 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -48,8 +48,6 @@ } intersphinx_disabled_domains = ["std"] -templates_path = ["_templates"] - # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This pattern also affects html_static_path and html_extra_path. diff --git a/docs/index.rst b/docs/index.rst index 5ae5061f0..5db81bfd0 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -7,3 +7,4 @@ tableauserverclient .. automodule:: tableauserverclient :members: + :imported-members: diff --git a/pyproject.toml b/pyproject.toml index 1128e30a4..c2a8e93d8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,7 +35,7 @@ repository = "https://github.com/tableau/server-client-python" [project.optional-dependencies] test = ["black==26.5.1", "build", "mypy==2.3.0", "pytest>=7.0", "pytest-cov", "pytest-subtests", "pytest-xdist", "requests-mock>=1.0,<2.0", "types-requests>=2.32.4.20250913"] -docs = ["sphinx", "tomli", "furo"] +docs = ["sphinx>=7,<9", "furo>=2024,<2027", "tomli; python_version < '3.11'"] [tool.setuptools.package-data] # Only include data for tableauserverclient, not for samples, test, docs diff --git a/tableauserverclient/models/job_item.py b/tableauserverclient/models/job_item.py index 82aa8e080..f684c22d4 100644 --- a/tableauserverclient/models/job_item.py +++ b/tableauserverclient/models/job_item.py @@ -27,7 +27,7 @@ class JobItem: Parameters ---------- - id : str + id_ : str The identifier of the job. job_type : str diff --git a/tableauserverclient/models/task_item.py b/tableauserverclient/models/task_item.py index a8a672a4a..b343f3c22 100644 --- a/tableauserverclient/models/task_item.py +++ b/tableauserverclient/models/task_item.py @@ -13,7 +13,7 @@ class TaskItem: Parameters ---------- - id : str + id_ : str The ID of the task. task_type : str