From 54ce10ee1ffeca64a8e41cab5b38b1859f73567e Mon Sep 17 00:00:00 2001 From: Brian Cantoni Date: Tue, 13 Oct 2026 22:14:16 -0700 Subject: [PATCH 1/4] Add Python 3.15 to test matrix, clarify 3.9 dropped previously --- .github/workflows/run-tests.yml | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index aab5d1cb3..0474b54a7 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -13,7 +13,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, macos-latest, windows-latest] - python-version: ['3.10', '3.11', '3.12', '3.13', '3.14', '3.14t'] + python-version: ['3.10', '3.11', '3.12', '3.13', '3.14', '3.14t', '3.15'] runs-on: ${{ matrix.os }} diff --git a/README.md b/README.md index 5c80f337e..181d08a24 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Use the Tableau Server Client (TSC) library to increase your productivity as you * Create users and groups. * Query projects, sites, and more. -This repository contains Python source code for the library and sample files showing how to use it. As of September 2024, support for Python 3.7 and 3.8 will be dropped - support for older versions of Python aims to match https://devguide.python.org/versions/ +This repository contains Python source code for the library and sample files showing how to use it. As of October 2026, support for Python 3.9 will be dropped - support for older versions of Python aims to match https://devguide.python.org/versions/ To see sample code that works directly with the REST API (in Java, Python, or Postman), visit the [REST API Samples](https://github.com/tableau/rest-api-samples) repo. From c3e914432d29809ce4d2c1663b8d70b606b23ca0 Mon Sep 17 00:00:00 2001 From: Brian Cantoni Date: Tue, 13 Oct 2026 22:18:01 -0700 Subject: [PATCH 2/4] Revise Python version support information in README Updated README to reflect the dropping of support for Python 3.9. Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 181d08a24..947287475 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Use the Tableau Server Client (TSC) library to increase your productivity as you * Create users and groups. * Query projects, sites, and more. -This repository contains Python source code for the library and sample files showing how to use it. As of October 2026, support for Python 3.9 will be dropped - support for older versions of Python aims to match https://devguide.python.org/versions/ +This repository contains Python source code for the library and sample files showing how to use it. As of October 2026, support for Python 3.9 has been dropped; support for older versions of Python aims to match https://devguide.python.org/versions/ To see sample code that works directly with the REST API (in Java, Python, or Postman), visit the [REST API Samples](https://github.com/tableau/rest-api-samples) repo. From 5e8dbfc4beaed4c87f2bb7269c0d941aec94face Mon Sep 17 00:00:00 2001 From: Brian Cantoni Date: Thu, 15 Oct 2026 15:04:09 -0700 Subject: [PATCH 3/4] Switch to kebab-case per GH Actions warning message --- .github/workflows/publish-pypi.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish-pypi.yml b/.github/workflows/publish-pypi.yml index 8bc11466d..f3290bec2 100644 --- a/.github/workflows/publish-pypi.yml +++ b/.github/workflows/publish-pypi.yml @@ -47,8 +47,8 @@ jobs: uses: pypa/gh-action-pypi-publish@release/v1 # license BSD-2 with: password: ${{ secrets.TEST_PYPI_API_TOKEN }} - repository_url: https://test.pypi.org/legacy/ - skip_existing: true + repository-url: https://test.pypi.org/legacy/ + skip-existing: true smoke-test-pypi: name: Smoke test from Test PyPI From 8a8f039c47dcdd56a2a8ad794accc07f237340ed Mon Sep 17 00:00:00 2001 From: Brian Cantoni Date: Thu, 15 Oct 2026 15:10:18 -0700 Subject: [PATCH 4/4] Update contributors script and current list Code changes courtesy of Cursor --- CONTRIBUTORS.md | 44 ++++++++++++++++++++++++++++------------- README.md | 2 +- getcontributors.py | 49 ++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 74 insertions(+), 21 deletions(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index a69cfff21..32d3699c4 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -4,36 +4,43 @@ The following people have contributed to this project to make it possible, and w ## Contributors -* [jacalata](https://github.com/jacalata) * [jorwoods](https://github.com/jorwoods) +* [jacalata](https://github.com/jacalata) * [t8y8](https://github.com/t8y8) * [bcantoni](https://github.com/bcantoni) * [shinchris](https://github.com/shinchris) +* [vchavatapalli](https://github.com/vchavatapalli) * [vogelsgesang](https://github.com/vogelsgesang) * [lbrendanl](https://github.com/lbrendanl) * [LGraber](https://github.com/LGraber) +* [dependabot[bot]](https://github.com/apps/dependabot) * [gaoang2148](https://github.com/gaoang2148) -* [benlower](https://github.com/benlower) * [liu-rebecca](https://github.com/liu-rebecca) +* [benlower](https://github.com/benlower) * [guodah](https://github.com/guodah) -* [jdomingu](https://github.com/jdomingu) * [kykrueger](https://github.com/kykrueger) +* [renoyjohnm](https://github.com/renoyjohnm) +* [jdomingu](https://github.com/jdomingu) * [jz-huang](https://github.com/jz-huang) * [opus-42](https://github.com/opus-42) -* [markm-io](https://github.com/markm-io) -* [graysonarts](https://github.com/graysonarts) +* [securehst](https://github.com/securehst) * [d45](https://github.com/d45) -* [preguraman](https://github.com/preguraman) +* [graysonarts](https://github.com/graysonarts) * [sotnich](https://github.com/sotnich) +* [casey-crawford-cfa](https://github.com/casey-crawford-cfa) +* [preguraman](https://github.com/preguraman) * [mmuttreja-tableau](https://github.com/mmuttreja-tableau) -* [dependabot[bot]](https://github.com/apps/dependabot) +* [vitorhonna](https://github.com/vitorhonna) +* [TrimPeachu](https://github.com/TrimPeachu) * [scuml](https://github.com/scuml) * [ovinis](https://github.com/ovinis) -* [FFMMM](https://github.com/FFMMM) * [martinbpeters](https://github.com/martinbpeters) * [talvalin](https://github.com/talvalin) +* [FFMMM](https://github.com/FFMMM) +* [Copilot](https://github.com/apps/copilot-swe-agent) * [dzucker-tab](https://github.com/dzucker-tab) * [a-torres-2](https://github.com/a-torres-2) +* [valsarajnivea](https://github.com/valsarajnivea) * [nnevalainen](https://github.com/nnevalainen) * [mbren](https://github.com/mbren) * [wolkiewiczk](https://github.com/wolkiewiczk) @@ -51,32 +58,41 @@ The following people have contributed to this project to make it possible, and w * [annematronic](https://github.com/annematronic) * [rshide](https://github.com/rshide) * [VathsalaAchar](https://github.com/VathsalaAchar) -* [TrimPeachu](https://github.com/TrimPeachu) -* [ajbosco](https://github.com/ajbosco) +* [toomyem](https://github.com/toomyem) +* [ma7tcsp](https://github.com/ma7tcsp) +* [bossenti](https://github.com/bossenti) +* [TableauKyle](https://github.com/TableauKyle) * [jimbodriven](https://github.com/jimbodriven) +* [joelclark](https://github.com/joelclark) * [ltiffanydev](https://github.com/ltiffanydev) * [martydertz](https://github.com/martydertz) * [r-richmond](https://github.com/r-richmond) * [sfarr15](https://github.com/sfarr15) +* [sparklingSky](https://github.com/sparklingSky) * [tagyoureit](https://github.com/tagyoureit) * [tjones-commits](https://github.com/tjones-commits) * [yoshichan5](https://github.com/yoshichan5) * [wlodi83](https://github.com/wlodi83) +* [ajbosco](https://github.com/ajbosco) +* [AlbertWangXu](https://github.com/AlbertWangXu) * [anipmehta](https://github.com/anipmehta) +* [BereketBirbo](https://github.com/BereketBirbo) * [cmtoomey](https://github.com/cmtoomey) +* [dxdc](https://github.com/dxdc) +* [KulykDmytro](https://github.com/KulykDmytro) +* [ecederstrand](https://github.com/ecederstrand) * [pes-magic](https://github.com/pes-magic) * [illonage](https://github.com/illonage) +* [Der-Henning](https://github.com/Der-Henning) * [jayvdb](https://github.com/jayvdb) * [jorgeFons](https://github.com/jorgeFons) * [Kovner](https://github.com/Kovner) * [LarsBreddemann](https://github.com/LarsBreddemann) * [lboynton](https://github.com/lboynton) +* [LehmD](https://github.com/LehmD) * [maddy-at-leisure](https://github.com/maddy-at-leisure) * [narcolino-tableau](https://github.com/narcolino-tableau) * [PatrickfBraz](https://github.com/PatrickfBraz) * [paulvic](https://github.com/paulvic) +* [RenaSpb](https://github.com/RenaSpb) * [shrmnk](https://github.com/shrmnk) -* [TableauKyle](https://github.com/TableauKyle) -* [bossenti](https://github.com/bossenti) -* [ma7tcsp](https://github.com/ma7tcsp) -* [toomyem](https://github.com/toomyem) diff --git a/README.md b/README.md index 947287475..b9b2d89c6 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ To see sample code that works directly with the REST API (in Java, Python, or Po For more information on installing and using TSC, see the documentation: -To contribute, see our [Developer Guide](https://tableau.github.io/server-client-python/docs/dev-guide). A list of all our contributors to date is in [CONTRIBUTORS.md]. +To contribute, see our [Developer Guide](https://tableau.github.io/server-client-python/docs/dev-guide). A list of all our contributors to date is in [CONTRIBUTORS.md](CONTRIBUTORS.md). ## License [![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Ftableau%2Fserver-client-python.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2Ftableau%2Fserver-client-python?ref=badge_large) diff --git a/getcontributors.py b/getcontributors.py index 54ca81cb2..50be3b169 100644 --- a/getcontributors.py +++ b/getcontributors.py @@ -1,9 +1,46 @@ -import json +import os +import subprocess + import requests +URL = "https://api.github.com/repos/tableau/server-client-python/contributors" + + +def github_token(): + token = os.environ.get("GITHUB_TOKEN") or os.environ.get("GH_TOKEN") + if token: + return token + try: + return subprocess.check_output(["gh", "auth", "token"], text=True, stderr=subprocess.DEVNULL).strip() or None + except (OSError, subprocess.CalledProcessError): + return None + + +def fetch_contributors(): + headers = {"Accept": "application/vnd.github+json", "User-Agent": "getcontributors"} + token = github_token() + if token: + headers["Authorization"] = f"Bearer {token}" + + contributors = [] + page = 1 + while True: + response = requests.get(URL, headers=headers, params={"per_page": 100, "page": page}, timeout=30) + payload = response.json() + if not response.ok or not isinstance(payload, list): + message = payload.get("message", payload) if isinstance(payload, dict) else payload + raise SystemExit(f"GitHub API error {response.status_code}: {message}") + if not payload: + break + contributors.extend(payload) + if len(payload) < 100: + break + page += 1 + return contributors + -logins = json.loads( - requests.get("https://api.github.com/repos/tableau/server-client-python/contributors?per_page=200").text -) -for login in logins: - print(f"* [{login["login"]}]({login["html_url"]})") +for person in fetch_contributors(): + login = person.get("login") + html_url = person.get("html_url") + if login and html_url: + print(f"* [{login}]({html_url})")