Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ Flow Production Tracking Python API Changelog

Here you can see the full list of changes between each Python API release.

v3.10.2 (2026 Jun 2)
=====================

- Update bundled certifi to version 2026.5.20.

v3.10.1 (2026 Feb 10)
=====================

Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

setup(
name="shotgun_api3",
version="3.10.0",
version="3.10.2",
description="Flow Production Tracking Python API",
long_description=readme,
author="Autodesk",
Expand Down
2 changes: 1 addition & 1 deletion shotgun_api3/lib/certifi/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from .core import contents, where

__all__ = ["contents", "where"]
__version__ = "2026.01.04"
__version__ = "2026.05.20"
630 changes: 27 additions & 603 deletions shotgun_api3/lib/certifi/cacert.pem

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion shotgun_api3/lib/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,5 @@
# This file is unused. It is left there so Github can warn us is a CVE is
# released for our dependencies.
httplib2==0.22.0
certifi==2026.1.4
certifi==2026.5.20
pyparsing==2.4.7
2 changes: 1 addition & 1 deletion shotgun_api3/shotgun.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@

# ----------------------------------------------------------------------------
# Version
__version__ = "3.10.0"
__version__ = "3.10.2"


# ----------------------------------------------------------------------------
Expand Down
105 changes: 105 additions & 0 deletions update_certifi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
#!/usr/bin/env python3

"""
Updates the bundled certifi module.

Run as "./update_certifi.py YYYY.MM.DD" to get a specific release from PyPI.
"""

import pathlib
import re
import shutil
import subprocess

Check notice on line 12 in update_certifi.py

View check run for this annotation

ShotGrid Chorus / security/bandit

B404: blacklist

Consider possible security implications associated with the subprocess module. secure coding id: PYTH-INJC-30.
import sys
import tempfile


class Utilities:
def download_wheel(self, version, dest_dir):
"""Download the certifi wheel from PyPI."""
print(f"Downloading certifi {version}")
subprocess.check_output(
[
"pip",
"download",
f"certifi=={version}",
"--no-deps",
"--index-url",
"https://pypi.org/simple/",
"-d",
str(dest_dir),
]
)

Check notice on line 32 in update_certifi.py

View check run for this annotation

ShotGrid Chorus / security/bandit

B607: start_process_with_partial_path

Starting a process with a partial executable path secure coding id: PYTH-INJC-30.

Check notice on line 32 in update_certifi.py

View check run for this annotation

ShotGrid Chorus / security/bandit

B603: subprocess_without_shell_equals_true

subprocess call - check for execution of untrusted input. secure coding id: PYTH-INJC-30.

def unzip_archive(self, file_path, temp_dir):
"""Unzip in a temp dir."""
print(f"Unzipping {file_path.name}")
subprocess.check_output(["unzip", str(file_path), "-d", str(temp_dir)])

Check notice on line 37 in update_certifi.py

View check run for this annotation

ShotGrid Chorus / security/bandit

B607: start_process_with_partial_path

Starting a process with a partial executable path secure coding id: PYTH-INJC-30.

Check notice on line 37 in update_certifi.py

View check run for this annotation

ShotGrid Chorus / security/bandit

B603: subprocess_without_shell_equals_true

subprocess call - check for execution of untrusted input. secure coding id: PYTH-INJC-30.

def remove_folder(self, path):
"""Remove a folder recursively."""
print(f"Removing the folder {path}")
shutil.rmtree(path, ignore_errors=True)

def git_remove(self, target):
print(f"Removing {target} in git.")
try:
subprocess.check_output(["git", "rm", "-rf"] + target)

Check notice on line 47 in update_certifi.py

View check run for this annotation

ShotGrid Chorus / security/bandit

B603: subprocess_without_shell_equals_true

subprocess call - check for execution of untrusted input. secure coding id: PYTH-INJC-30.
except Exception:
pass

Check notice on line 49 in update_certifi.py

View check run for this annotation

ShotGrid Chorus / security/bandit

B110: try_except_pass

Try, Except, Pass detected. secure coding id: PYTH-GEAP-50.

def copy_folder(self, source, target):
"""Copy a folder recursively."""
shutil.copytree(source, target)

def update_requirements(self, req_file, version):
"""Update the certifi version pin in requirements.txt."""
content = req_file.read_text()
content = re.sub(r"certifi==[\d.]+", f"certifi=={version}", content)
req_file.write_text(content)


def main(temp_path, repo_root, version):
certifi_dir = repo_root / "shotgun_api3" / "lib" / "certifi"
req_file = repo_root / "shotgun_api3" / "lib" / "requirements.txt"

utilities = Utilities()

# Download the wheel from PyPI
utilities.download_wheel(version, temp_path)

# Find the downloaded wheel file
wheels = list(temp_path.glob("certifi-*.whl"))
if not wheels:
raise RuntimeError("No certifi wheel found after download")

# Unzip into a temp dir
unzipped = temp_path / "unzipped"
unzipped.mkdir()
utilities.unzip_archive(wheels[0], unzipped)

# Remove old certifi from git and disk
utilities.git_remove([str(certifi_dir)])
utilities.remove_folder(certifi_dir)

# Copy new certifi into place (only the certifi/ package, not .dist-info)
print("Copying new version of certifi")
utilities.copy_folder(str(unzipped / "certifi"), str(certifi_dir))

# Update requirements.txt version pin
print("Updating requirements.txt")
utilities.update_requirements(req_file, version)

# Stage changes
print("Adding to git")
subprocess.check_output(
["git", "add", str(certifi_dir), str(req_file)]
) # nosec B607

Check notice on line 97 in update_certifi.py

View check run for this annotation

ShotGrid Chorus / security/bandit

B603: subprocess_without_shell_equals_true

subprocess call - check for execution of untrusted input. secure coding id: PYTH-INJC-30.


if __name__ == "__main__":
try:
temp_path = pathlib.Path(tempfile.mkdtemp())
main(temp_path, pathlib.Path(__file__).parent, sys.argv[1])
finally:
shutil.rmtree(temp_path)
2 changes: 1 addition & 1 deletion update_httplib2.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"""
Updates the httplib2 module.

Run as "./upgrade_httplib2.py vX.Y.Z" to get a specific release from github.
Run as "./update_httplib2.py vX.Y.Z" to get a specific release from github.
"""

import pathlib
Expand Down
Loading