From d5dd9b09ab80b54c35472b93a4a8545b040e9417 Mon Sep 17 00:00:00 2001 From: Abhinav Dhiman Date: Fri, 22 Aug 2025 15:18:16 +0530 Subject: [PATCH 01/26] deps: enable urllib3 2.x on Py>=3.9; keep Py<3.9 on urllib3<2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add env-marked pins: - Py>=3.9: requests>=2.32.2, urllib3!=2.0.0,<3 - 3.7–3.8: requests<2.32, urllib3<2 - 3.6: requests<2.28, urllib3<2 - Bump requests-toolbelt to >=1.0.0 - README: document per-Python resolver behavior - CI: matrix runs both urllib3<2 and urllib3>=2 on appropriate Pythons Refs: - Requests now requires Python >=3.9; 2.32.0/2.32.1 yanked (start at 2.32.2). - urllib3 2.x requires Python >=3.9. - requests-toolbelt 1.0.0 aligns with urllib3 2.x. --- .github/workflows/test.yml | 2 +- requirements/requirements.txt | 21 ++++++++++++++++++--- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 17ce4710..bd756dff 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-20.04 strategy: matrix: - python: [3.7, 3.8, 3.9, '3.10'] + python: [3.7, 3.8, 3.9, '3.10', '3.11', '3.12'] steps: - uses: actions/checkout@v1 - name: Setup Python diff --git a/requirements/requirements.txt b/requirements/requirements.txt index 7758d169..619f7ec6 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -1,3 +1,18 @@ -requests>=2.22.0 -requests_toolbelt==0.10.1 -urllib3==1.26.* \ No newline at end of file +requests_toolbelt>=1.0.0 + +# ------------ Python >= 3.9 ------------ +# Requests 2.32.0/2.32.1 were yanked; start at 2.32.2. +# urllib3 2.x requires Python >=3.9; exclude 2.0.0 (known bug). +requests>=2.32.2; python_version >= "3.9" +urllib3!=2.0.0,<3; python_version >= "3.9" + +# ------------ 3.7 <= Python < 3.9 ------------ +# Latest Requests that still supports 3.7/3.8 is 2.31.x. +requests>=2.22.0,<2.32; python_version >= "3.7" and python_version < "3.9" +# urllib3<2 keeps behavior consistent on these Pythons. +urllib3<2; python_version >= "3.7" and python_version < "3.9" + +# ------------ Python < 3.7 (i.e., 3.6) ------------ +# 2.27.x was the last Requests series for 3.6. +requests>=2.22.0,<2.28; python_version < "3.7" +urllib3<2; python_version < "3.7" \ No newline at end of file From 3dd09e13510257ca357ed21e25005d09046baf9b Mon Sep 17 00:00:00 2001 From: Abhinav Dhiman Date: Fri, 22 Aug 2025 15:18:16 +0530 Subject: [PATCH 02/26] ci: update Python and urllib3 version support across workflows and documentation --- .github/workflows/publish.yml | 19 +++++++++++++++++-- .github/workflows/test.yml | 17 ++++++++++++++++- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index ce37efd1..e44bbbad 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -6,16 +6,31 @@ on: jobs: deploy: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest strategy: matrix: - python: [3.7, 3.8, 3.9, '3.10'] + python: [3.7, 3.8, 3.9, '3.10', '3.11', '3.12'] + urllib3-line: ["lt2", "ge2"] + exclude: + - python-version: "3.7" + urllib3-line: "ge2" + - python-version: "3.8" + urllib3-line: "ge2" steps: - uses: actions/checkout@v1 - name: Set up Python uses: actions/setup-python@v1 with: python-version: ${{ matrix.python }} + - name: Install deps + run: | + pip install -r requirements/requirements.txt + if [ "${{ matrix.urllib3-line }}" = "lt2" ]; then + pip install "urllib3<2" + else + pip install "urllib3!=2.0.0,<3" + fi + pip install -e . - name: Install Tox and any other packages run: | python -m pip install --upgrade pip diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index bd756dff..4ab60bac 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -4,16 +4,31 @@ on: [push, pull_request] jobs: build: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest strategy: matrix: python: [3.7, 3.8, 3.9, '3.10', '3.11', '3.12'] + urllib3-line: ["lt2", "ge2"] + exclude: + - python-version: "3.7" + urllib3-line: "ge2" + - python-version: "3.8" + urllib3-line: "ge2" steps: - uses: actions/checkout@v1 - name: Setup Python uses: actions/setup-python@v1 with: python-version: ${{ matrix.python }} + - name: Install deps + run: | + pip install -r requirements/requirements.txt + if [ "${{ matrix.urllib3-line }}" = "lt2" ]; then + pip install "urllib3<2" + else + pip install "urllib3!=2.0.0,<3" + fi + pip install -e . - name: Install Tox and any other packages run: pip install -r requirements/test.txt - name: Run Tox From 75ec90bef525925552e3f2ffd396df76fa2ef6e8 Mon Sep 17 00:00:00 2001 From: Abhinav Dhiman Date: Fri, 22 Aug 2025 20:51:44 +0530 Subject: [PATCH 03/26] build: update dependency requirements --- requirements/test.txt | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/requirements/test.txt b/requirements/test.txt index 2d600d65..09f3c332 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -1,7 +1,4 @@ -requests>=2.22.0 black==19.10b0 coverage==4.5.4 tox==3.14.2 -responses==0.17.0 -requests_toolbelt==0.10.1 -urllib3==1.26.* \ No newline at end of file +responses==0.17.0 \ No newline at end of file From cb1d6e919f9a8bee39a0e4f153293bec128fb682 Mon Sep 17 00:00:00 2001 From: Abhinav Dhiman Date: Fri, 22 Aug 2025 20:53:58 +0530 Subject: [PATCH 04/26] fix: correct python version variable name in CI workflow exclusions --- .github/workflows/publish.yml | 4 ++-- .github/workflows/test.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index e44bbbad..9603b3cc 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -12,9 +12,9 @@ jobs: python: [3.7, 3.8, 3.9, '3.10', '3.11', '3.12'] urllib3-line: ["lt2", "ge2"] exclude: - - python-version: "3.7" + - python: "3.7" urllib3-line: "ge2" - - python-version: "3.8" + - python: "3.8" urllib3-line: "ge2" steps: - uses: actions/checkout@v1 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4ab60bac..709e2008 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,9 +10,9 @@ jobs: python: [3.7, 3.8, 3.9, '3.10', '3.11', '3.12'] urllib3-line: ["lt2", "ge2"] exclude: - - python-version: "3.7" + - python: "3.7" urllib3-line: "ge2" - - python-version: "3.8" + - python: "3.8" urllib3-line: "ge2" steps: - uses: actions/checkout@v1 From e97b8463fb1f661604cf8606b1b390665e3d9a8b Mon Sep 17 00:00:00 2001 From: Abhinav Dhiman Date: Fri, 22 Aug 2025 21:18:26 +0530 Subject: [PATCH 05/26] ci: update GitHub Actions to use Ubuntu 22.04 runner --- .github/workflows/publish.yml | 18 +++++++++--------- .github/workflows/test.yml | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 9603b3cc..799b92fa 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -6,16 +6,16 @@ on: jobs: deploy: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 strategy: - matrix: - python: [3.7, 3.8, 3.9, '3.10', '3.11', '3.12'] - urllib3-line: ["lt2", "ge2"] - exclude: - - python: "3.7" - urllib3-line: "ge2" - - python: "3.8" - urllib3-line: "ge2" + matrix: + python: [3.7, 3.8, 3.9, '3.10', '3.11', '3.12'] + urllib3-line: ["lt2", "ge2"] + exclude: + - python: "3.7" + urllib3-line: "ge2" + - python: "3.8" + urllib3-line: "ge2" steps: - uses: actions/checkout@v1 - name: Set up Python diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 709e2008..3a8eb1cb 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -4,7 +4,7 @@ on: [push, pull_request] jobs: build: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 strategy: matrix: python: [3.7, 3.8, 3.9, '3.10', '3.11', '3.12'] From 21bdf4f9d41dce7756d000e5b5e6aa7c4a133172 Mon Sep 17 00:00:00 2001 From: Abhinav Dhiman Date: Fri, 22 Aug 2025 21:19:55 +0530 Subject: [PATCH 06/26] ci: upgrade GitHub Actions checkout and setup-python from v1 to v5 --- .github/workflows/publish.yml | 4 ++-- .github/workflows/test.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 799b92fa..ca2c3de2 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -17,9 +17,9 @@ jobs: - python: "3.8" urllib3-line: "ge2" steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v5 - name: Set up Python - uses: actions/setup-python@v1 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python }} - name: Install deps diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3a8eb1cb..7bb1803f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -15,9 +15,9 @@ jobs: - python: "3.8" urllib3-line: "ge2" steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v5 - name: Setup Python - uses: actions/setup-python@v1 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python }} - name: Install deps From 3ab437c91b43825f2925feb95e48d67da1ff2cfe Mon Sep 17 00:00:00 2001 From: Abhinav Dhiman Date: Fri, 22 Aug 2025 21:22:10 +0530 Subject: [PATCH 07/26] ci: reorder pip install commands in test workflow for better dependency management --- .github/workflows/test.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7bb1803f..01a59418 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -23,14 +23,13 @@ jobs: - name: Install deps run: | pip install -r requirements/requirements.txt + pip install -r requirements/test.txt if [ "${{ matrix.urllib3-line }}" = "lt2" ]; then pip install "urllib3<2" else pip install "urllib3!=2.0.0,<3" fi pip install -e . - - name: Install Tox and any other packages - run: pip install -r requirements/test.txt - name: Run Tox run: tox -e py - name: Upload Coverage to codecov From 19a1dba9b2388c74e015e3a42b82edeee4b20367 Mon Sep 17 00:00:00 2001 From: Abhinav Dhiman Date: Fri, 22 Aug 2025 21:53:18 +0530 Subject: [PATCH 08/26] build: update test dependencies and Python version compatibility constraints --- .github/workflows/test.yml | 1 - requirements/test.txt | 19 +++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 01a59418..b78bd6a0 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -22,7 +22,6 @@ jobs: python-version: ${{ matrix.python }} - name: Install deps run: | - pip install -r requirements/requirements.txt pip install -r requirements/test.txt if [ "${{ matrix.urllib3-line }}" = "lt2" ]; then pip install "urllib3<2" diff --git a/requirements/test.txt b/requirements/test.txt index 09f3c332..9175f026 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -1,3 +1,22 @@ +requests_toolbelt>=1.0.0 + +# ------------ Python >= 3.9 ------------ +# Requests 2.32.0/2.32.1 were yanked; start at 2.32.2. +# urllib3 2.x requires Python >=3.9; exclude 2.0.0 (known bug). +requests>=2.32.2; python_version >= "3.9" +urllib3!=2.0.0,<3; python_version >= "3.9" + +# ------------ 3.7 <= Python < 3.9 ------------ +# Latest Requests that still supports 3.7/3.8 is 2.31.x. +requests>=2.22.0,<2.32; python_version >= "3.7" and python_version < "3.9" +# urllib3<2 keeps behavior consistent on these Pythons. +urllib3<2; python_version >= "3.7" and python_version < "3.9" + +# ------------ Python < 3.7 (i.e., 3.6) ------------ +# 2.27.x was the last Requests series for 3.6. +requests>=2.22.0,<2.28; python_version < "3.7" +urllib3<2; python_version < "3.7" + black==19.10b0 coverage==4.5.4 tox==3.14.2 From 53e6aafb263bdeb943964124d4f80c0c779f9b77 Mon Sep 17 00:00:00 2001 From: Abhinav Dhiman Date: Fri, 22 Aug 2025 22:33:36 +0530 Subject: [PATCH 09/26] chore: disable test cases for ge2 --- .github/workflows/test.yml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b78bd6a0..638dfd30 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,13 +7,15 @@ jobs: runs-on: ubuntu-22.04 strategy: matrix: + # python: [3.7, 3.8, 3.9, '3.10', '3.11', '3.12'] python: [3.7, 3.8, 3.9, '3.10', '3.11', '3.12'] - urllib3-line: ["lt2", "ge2"] - exclude: - - python: "3.7" - urllib3-line: "ge2" - - python: "3.8" - urllib3-line: "ge2" + # urllib3-line: ["lt2", "ge2"] + urllib3-line: ["lt2"] + # exclude: + # - python: "3.7" + # urllib3-line: "ge2" + # - python: "3.8" + # urllib3-line: "ge2" steps: - uses: actions/checkout@v5 - name: Setup Python From 628cccf1c2390e4ba0053631f2ea067477054654 Mon Sep 17 00:00:00 2001 From: Abhinav Dhiman Date: Mon, 25 Aug 2025 14:08:54 +0530 Subject: [PATCH 10/26] ci: consolidate CI workflows and update test dependencies for Python version compatibility --- .github/workflows/test.yml | 14 ++++++-------- requirements/requirements.txt | 14 ++++++-------- requirements/test.txt | 15 ++++++--------- 3 files changed, 18 insertions(+), 25 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 638dfd30..b78bd6a0 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,15 +7,13 @@ jobs: runs-on: ubuntu-22.04 strategy: matrix: - # python: [3.7, 3.8, 3.9, '3.10', '3.11', '3.12'] python: [3.7, 3.8, 3.9, '3.10', '3.11', '3.12'] - # urllib3-line: ["lt2", "ge2"] - urllib3-line: ["lt2"] - # exclude: - # - python: "3.7" - # urllib3-line: "ge2" - # - python: "3.8" - # urllib3-line: "ge2" + urllib3-line: ["lt2", "ge2"] + exclude: + - python: "3.7" + urllib3-line: "ge2" + - python: "3.8" + urllib3-line: "ge2" steps: - uses: actions/checkout@v5 - name: Setup Python diff --git a/requirements/requirements.txt b/requirements/requirements.txt index 619f7ec6..1f74ae82 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -1,18 +1,16 @@ requests_toolbelt>=1.0.0 # ------------ Python >= 3.9 ------------ -# Requests 2.32.0/2.32.1 were yanked; start at 2.32.2. -# urllib3 2.x requires Python >=3.9; exclude 2.0.0 (known bug). requests>=2.32.2; python_version >= "3.9" -urllib3!=2.0.0,<3; python_version >= "3.9" +urllib3<3; python_version >= "3.9" +responses>=0.25.0; python_version >= "3.9" # ------------ 3.7 <= Python < 3.9 ------------ -# Latest Requests that still supports 3.7/3.8 is 2.31.x. requests>=2.22.0,<2.32; python_version >= "3.7" and python_version < "3.9" -# urllib3<2 keeps behavior consistent on these Pythons. urllib3<2; python_version >= "3.7" and python_version < "3.9" +responses>=0.23.0,<0.25; python_version >= "3.7" and python_version < "3.9" -# ------------ Python < 3.7 (i.e., 3.6) ------------ -# 2.27.x was the last Requests series for 3.6. +# ------------ Python < 3.7 ------------ requests>=2.22.0,<2.28; python_version < "3.7" -urllib3<2; python_version < "3.7" \ No newline at end of file +urllib3<2; python_version < "3.7" +responses>=0.20.0,<0.22; python_version < "3.7" \ No newline at end of file diff --git a/requirements/test.txt b/requirements/test.txt index 9175f026..460a2005 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -1,23 +1,20 @@ requests_toolbelt>=1.0.0 # ------------ Python >= 3.9 ------------ -# Requests 2.32.0/2.32.1 were yanked; start at 2.32.2. -# urllib3 2.x requires Python >=3.9; exclude 2.0.0 (known bug). requests>=2.32.2; python_version >= "3.9" -urllib3!=2.0.0,<3; python_version >= "3.9" +urllib3<3; python_version >= "3.9" +responses>=0.25.0; python_version >= "3.9" # ------------ 3.7 <= Python < 3.9 ------------ -# Latest Requests that still supports 3.7/3.8 is 2.31.x. requests>=2.22.0,<2.32; python_version >= "3.7" and python_version < "3.9" -# urllib3<2 keeps behavior consistent on these Pythons. urllib3<2; python_version >= "3.7" and python_version < "3.9" +responses>=0.23.0,<0.25; python_version >= "3.7" and python_version < "3.9" -# ------------ Python < 3.7 (i.e., 3.6) ------------ -# 2.27.x was the last Requests series for 3.6. +# ------------ Python < 3.7 ------------ requests>=2.22.0,<2.28; python_version < "3.7" urllib3<2; python_version < "3.7" +responses>=0.20.0,<0.22; python_version < "3.7" black==19.10b0 coverage==4.5.4 -tox==3.14.2 -responses==0.17.0 \ No newline at end of file +tox==3.14.2 \ No newline at end of file From 2365f8fe875c76eac9f280d72b293487870deefe Mon Sep 17 00:00:00 2001 From: Abhinav Dhiman Date: Tue, 26 Aug 2025 02:18:05 +0530 Subject: [PATCH 11/26] ci: update Python version support --- .github/workflows/test.yml | 2 +- requirements/requirements.txt | 5 +---- requirements/test.txt | 8 +++++--- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b78bd6a0..23e2a85d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-22.04 strategy: matrix: - python: [3.7, 3.8, 3.9, '3.10', '3.11', '3.12'] + python: [3.6, 3.7, 3.8, 3.9, '3.10', '3.11', '3.12'] urllib3-line: ["lt2", "ge2"] exclude: - python: "3.7" diff --git a/requirements/requirements.txt b/requirements/requirements.txt index 1f74ae82..4bf508c7 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -3,14 +3,11 @@ requests_toolbelt>=1.0.0 # ------------ Python >= 3.9 ------------ requests>=2.32.2; python_version >= "3.9" urllib3<3; python_version >= "3.9" -responses>=0.25.0; python_version >= "3.9" # ------------ 3.7 <= Python < 3.9 ------------ requests>=2.22.0,<2.32; python_version >= "3.7" and python_version < "3.9" urllib3<2; python_version >= "3.7" and python_version < "3.9" -responses>=0.23.0,<0.25; python_version >= "3.7" and python_version < "3.9" # ------------ Python < 3.7 ------------ requests>=2.22.0,<2.28; python_version < "3.7" -urllib3<2; python_version < "3.7" -responses>=0.20.0,<0.22; python_version < "3.7" \ No newline at end of file +urllib3<2; python_version < "3.7" \ No newline at end of file diff --git a/requirements/test.txt b/requirements/test.txt index 460a2005..bc41da0a 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -3,17 +3,19 @@ requests_toolbelt>=1.0.0 # ------------ Python >= 3.9 ------------ requests>=2.32.2; python_version >= "3.9" urllib3<3; python_version >= "3.9" -responses>=0.25.0; python_version >= "3.9" + # ------------ 3.7 <= Python < 3.9 ------------ requests>=2.22.0,<2.32; python_version >= "3.7" and python_version < "3.9" urllib3<2; python_version >= "3.7" and python_version < "3.9" -responses>=0.23.0,<0.25; python_version >= "3.7" and python_version < "3.9" # ------------ Python < 3.7 ------------ requests>=2.22.0,<2.28; python_version < "3.7" urllib3<2; python_version < "3.7" -responses>=0.20.0,<0.22; python_version < "3.7" + +responses>=0.25.0; python_version >= "3.8" +responses>=0.18.0,<0.25; python_version >= "3.7" and python_version < "3.8" +responses<0.18.0; python_version < "3.7" black==19.10b0 coverage==4.5.4 From 342d70154b49b8370f306c27c301a9bf421b1550 Mon Sep 17 00:00:00 2001 From: Abhinav Dhiman Date: Tue, 26 Aug 2025 11:45:16 +0530 Subject: [PATCH 12/26] chore: removed 3.6 from test --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 23e2a85d..b78bd6a0 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-22.04 strategy: matrix: - python: [3.6, 3.7, 3.8, 3.9, '3.10', '3.11', '3.12'] + python: [3.7, 3.8, 3.9, '3.10', '3.11', '3.12'] urllib3-line: ["lt2", "ge2"] exclude: - python: "3.7" From 3ed267f3f85ea3fa5e257b6e41c8cdbd4c728201 Mon Sep 17 00:00:00 2001 From: Abhinav Dhiman Date: Tue, 26 Aug 2025 23:13:20 +0530 Subject: [PATCH 13/26] test: fix --- .github/workflows/test.yml | 2 +- tests/test_custom_metadata_fields_ops.py | 2 +- tests/test_files_ops.py | 10 +++++----- tests/test_folder_ops.py | 1 - tox.ini | 2 +- 5 files changed, 8 insertions(+), 9 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b78bd6a0..19c362fb 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-22.04 strategy: matrix: - python: [3.7, 3.8, 3.9, '3.10', '3.11', '3.12'] + python: [3.7, 3.8, 3.9, '3.10', '3.11', '3.12', '3.13'] urllib3-line: ["lt2", "ge2"] exclude: - python: "3.7" diff --git a/tests/test_custom_metadata_fields_ops.py b/tests/test_custom_metadata_fields_ops.py index 49b2e030..20348baa 100644 --- a/tests/test_custom_metadata_fields_ops.py +++ b/tests/test_custom_metadata_fields_ops.py @@ -303,7 +303,7 @@ def test_delete_custom_metadata_fields_succeeds(self): URL.API_BASE_URL = "http://test.com" url = "{}/v1/customMetadataFields/{}".format(URL.API_BASE_URL, self.field_id) headers = create_headers_for_test() - responses.add(responses.DELETE, url, status=204, headers=headers, body="{}") + responses.add(responses.DELETE, url, status=204, headers=headers) resp = self.client.delete_custom_metadata_field(self.field_id) mock_response_metadata = { diff --git a/tests/test_files_ops.py b/tests/test_files_ops.py index 613406ef..71e7d042 100644 --- a/tests/test_files_ops.py +++ b/tests/test_files_ops.py @@ -1298,7 +1298,7 @@ def test_file_delete_succeeds(self): headers = {"Content-Type": "application/json"} headers.update(get_auth_headers_for_test()) - responses.add(responses.DELETE, url, body="{}", status=204, headers=headers) + responses.add(responses.DELETE, url , status=204, headers=headers) resp = self.client.delete_file(self.file_id) @@ -2466,7 +2466,7 @@ def test_delete_file_version_succeeds(self) -> None: ) headers = {"Content-Type": "application/json"} headers.update(create_headers_for_test()) - responses.add(responses.DELETE, url, status=204, headers=headers, body="{}") + responses.add(responses.DELETE, url, status=204, headers=headers ) resp = self.client.delete_file_version(self.file_id, self.version_id) mock_response_metadata = { @@ -2534,7 +2534,7 @@ def test_copy_file_succeeds(self) -> None: url = "{}/v1/files/copy".format(URL.API_BASE_URL) headers = {"Content-Type": "application/json"} headers.update(create_headers_for_test()) - responses.add(responses.POST, url, status=204, headers=headers, body="{}") + responses.add(responses.POST, url, status=204, headers=headers) resp = self.client.copy_file( options=CopyFileRequestOptions( @@ -2581,7 +2581,7 @@ def test_copy_file_succeeds_without_include_file_versions(self) -> None: url = "{}/v1/files/copy".format(URL.API_BASE_URL) headers = {"Content-Type": "application/json"} headers.update(create_headers_for_test()) - responses.add(responses.POST, url, status=204, headers=headers, body="{}") + responses.add(responses.POST, url, status=204, headers=headers ) resp = self.client.copy_file( options=CopyFileRequestOptions( @@ -2663,7 +2663,7 @@ def test_move_file_succeeds(self) -> None: url = "{}/v1/files/move".format(URL.API_BASE_URL) headers = {"Content-Type": "application/json"} headers.update(create_headers_for_test()) - responses.add(responses.POST, url, status=204, headers=headers, body="{}") + responses.add(responses.POST, url, status=204, headers=headers ) resp = self.client.move_file( options=MoveFileRequestOptions( diff --git a/tests/test_folder_ops.py b/tests/test_folder_ops.py index 5a5255b9..f955b717 100644 --- a/tests/test_folder_ops.py +++ b/tests/test_folder_ops.py @@ -154,7 +154,6 @@ def test_delete_folder_succeeds(self): responses.DELETE, url, status=204, - body="{}", ) resp = self.client.delete_folder( options=DeleteFolderRequestOptions(folder_path="/folderName") diff --git a/tox.ini b/tox.ini index b67c3500..ad884c34 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py36, py37, py38, py39, py310 +envlist = py36, py37, py38, py39, py310, py311, py312, py313 skipsdist = True [testenv] From 07334099d2496f24259bbdf322ddf4044b18b721 Mon Sep 17 00:00:00 2001 From: Abhinav Dhiman Date: Tue, 26 Aug 2025 23:18:39 +0530 Subject: [PATCH 14/26] chore: updated version of coverage --- requirements/test.txt | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/requirements/test.txt b/requirements/test.txt index bc41da0a..2038766b 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -3,20 +3,24 @@ requests_toolbelt>=1.0.0 # ------------ Python >= 3.9 ------------ requests>=2.32.2; python_version >= "3.9" urllib3<3; python_version >= "3.9" - +coverage>=7.5.0; python_version >= "3.9" and python_version < "3.13" +coverage>=7.6.0; python_version >= "3.13" # ------------ 3.7 <= Python < 3.9 ------------ requests>=2.22.0,<2.32; python_version >= "3.7" and python_version < "3.9" urllib3<2; python_version >= "3.7" and python_version < "3.9" +coverage>=5.0,<7.0; python_version >= "3.7" and python_version < "3.9" # ------------ Python < 3.7 ------------ requests>=2.22.0,<2.28; python_version < "3.7" urllib3<2; python_version < "3.7" +coverage==4.5.4; python_version < "3.7" +# ------------ responses versions ------------ responses>=0.25.0; python_version >= "3.8" responses>=0.18.0,<0.25; python_version >= "3.7" and python_version < "3.8" responses<0.18.0; python_version < "3.7" +# ------------ Dev tools ------------ black==19.10b0 -coverage==4.5.4 -tox==3.14.2 \ No newline at end of file +tox==3.14.2 From 4b82fa2b713fb02f0cbe8c06b4aef75b7064cb11 Mon Sep 17 00:00:00 2001 From: Abhinav Dhiman Date: Tue, 26 Aug 2025 23:27:13 +0530 Subject: [PATCH 15/26] chore: updated dev dependencies --- requirements/test.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/requirements/test.txt b/requirements/test.txt index 2038766b..e75f2753 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -3,8 +3,8 @@ requests_toolbelt>=1.0.0 # ------------ Python >= 3.9 ------------ requests>=2.32.2; python_version >= "3.9" urllib3<3; python_version >= "3.9" -coverage>=7.5.0; python_version >= "3.9" and python_version < "3.13" coverage>=7.6.0; python_version >= "3.13" +coverage>=7.5.0; python_version >= "3.9" and python_version < "3.13" # ------------ 3.7 <= Python < 3.9 ------------ requests>=2.22.0,<2.32; python_version >= "3.7" and python_version < "3.9" @@ -21,6 +21,6 @@ responses>=0.25.0; python_version >= "3.8" responses>=0.18.0,<0.25; python_version >= "3.7" and python_version < "3.8" responses<0.18.0; python_version < "3.7" -# ------------ Dev tools ------------ -black==19.10b0 +black>=24.8.0; python_version >= "3.8" +black==19.10b0; python_version < "3.8" tox==3.14.2 From 28d0ff7fcd3dedd701c85d1ce669620f35f50fa9 Mon Sep 17 00:00:00 2001 From: Abhinav Dhiman Date: Tue, 26 Aug 2025 23:35:18 +0530 Subject: [PATCH 16/26] chore: update tox version for 3.13 --- requirements/test.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/requirements/test.txt b/requirements/test.txt index e75f2753..e2291fbe 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -23,4 +23,7 @@ responses<0.18.0; python_version < "3.7" black>=24.8.0; python_version >= "3.8" black==19.10b0; python_version < "3.8" -tox==3.14.2 + +tox>=4; python_version >= "3.13" +tox==3.14.2; python_version < "3.13" + From c3adaccfab7356ba1dc3a2a1ebbdfabd49d4489b Mon Sep 17 00:00:00 2001 From: Abhinav Dhiman Date: Wed, 27 Aug 2025 01:24:07 +0530 Subject: [PATCH 17/26] style: update Content-Type header to use only application/json in test files --- tests/test_custom_metadata_fields_ops.py | 14 +++++------ tests/test_files_ops.py | 30 ++++++++++++------------ tests/test_tags_ops.py | 6 ++--- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/tests/test_custom_metadata_fields_ops.py b/tests/test_custom_metadata_fields_ops.py index 20348baa..e5084933 100644 --- a/tests/test_custom_metadata_fields_ops.py +++ b/tests/test_custom_metadata_fields_ops.py @@ -422,7 +422,7 @@ def test_create_custom_metadata_fields_succeeds_with_type_number(self): }, "httpStatusCode": 201, "headers": { - "Content-Type": "text/plain, application/json", + "Content-Type": "application/json", "Accept-Encoding": "gzip, deflate", "Authorization": "Basic ZmFrZTEyMjo=", }, @@ -493,7 +493,7 @@ def test_create_custom_metadata_fields_succeeds_with_type_textarea(self): mock_response_metadata = { "headers": { - "Content-Type": "text/plain, application/json", + "Content-Type": "application/json", "Accept-Encoding": "gzip, deflate", "Authorization": "Basic ZmFrZTEyMjo=", }, @@ -575,7 +575,7 @@ def test_create_custom_metadata_fields_succeeds_with_type_date(self): mock_response_metadata = { "headers": { - "Content-Type": "text/plain, application/json", + "Content-Type": "application/json", "Accept-Encoding": "gzip, deflate", "Authorization": "Basic ZmFrZTEyMjo=", }, @@ -653,7 +653,7 @@ def test_create_custom_metadata_fields_succeeds_with_type_boolean(self): mock_response_metadata = { "headers": { - "Content-Type": "text/plain, application/json", + "Content-Type": "application/json", "Accept-Encoding": "gzip, deflate", "Authorization": "Basic ZmFrZTEyMjo=", }, @@ -729,7 +729,7 @@ def test_create_custom_metadata_fields_succeeds_with_type_single_select(self): mock_response_metadata = { "headers": { - "Content-Type": "text/plain, application/json", + "Content-Type": "application/json", "Accept-Encoding": "gzip, deflate", "Authorization": "Basic ZmFrZTEyMjo=", }, @@ -809,7 +809,7 @@ def test_create_custom_metadata_fields_succeeds_with_type_multi_select(self): mock_response_metadata = { "headers": { - "Content-Type": "text/plain, application/json", + "Content-Type": "application/json", "Accept-Encoding": "gzip, deflate", "Authorization": "Basic ZmFrZTEyMjo=", }, @@ -892,7 +892,7 @@ def test_update_custom_metadata_fields_succeeds(self): }, "httpStatusCode": 200, "headers": { - "Content-Type": "text/plain, application/json", + "Content-Type": "application/json", "Accept-Encoding": "gzip, deflate", "Authorization": "Basic ZmFrZTEyMjo=", }, diff --git a/tests/test_files_ops.py b/tests/test_files_ops.py index 71e7d042..29a7aaf0 100644 --- a/tests/test_files_ops.py +++ b/tests/test_files_ops.py @@ -1171,7 +1171,7 @@ def test_bulk_file_delete_succeeds(self): "raw": {"successfullyDeletedFileIds": ["fake_123", "fake_222"]}, "httpStatusCode": 200, "headers": { - "Content-Type": "text/plain, application/json", + "Content-Type": "application/json", "Authorization": "Basic ZmFrZTEyMjo=", }, } @@ -1212,7 +1212,7 @@ def test_bulk_file_delete_succeeds_and_recieves_extra_non_breaking_changes_from_ "raw": {"successfullyDeletedFileIds": ["fake_123"],"nonDeletedFields":["fake_222"]}, "httpStatusCode": 200, "headers": { - "Content-Type": "text/plain, application/json", + "Content-Type": "application/json", "Authorization": "Basic ZmFrZTEyMjo=", }, } @@ -1304,7 +1304,7 @@ def test_file_delete_succeeds(self): mock_response_metadata = { "headers": { - "Content-Type": "text/plain, application/json", + "Content-Type": "application/json", "Authorization": "Basic ZmFrZTEyMjo=", }, "httpStatusCode": 204, @@ -1750,7 +1750,7 @@ def test_update_file_details_succeeds_with_id(self): ) mock_response_metadata = { "headers": { - "Content-Type": "text/plain, application/json", + "Content-Type": "application/json", "Authorization": "Basic ZmFrZTEyMjo=", }, "http_status_code": 200, @@ -1889,7 +1889,7 @@ def test_update_file_publish_status_succeeds_(self): ) mock_response_metadata = { "headers": { - "Content-Type": "text/plain, application/json", + "Content-Type": "application/json", "Authorization": "Basic ZmFrZTEyMjo=", }, "http_status_code": 200, @@ -2228,7 +2228,7 @@ def test_get_file_versions_succeeds_with_id(self): ], "http_status_code": 200, "headers": { - "Content-Type": "text/plain, application/json", + "Content-Type": "application/json", "Authorization": "Basic ZmFrZTEyMjo=", }, } @@ -2338,7 +2338,7 @@ def test_get_file_version_details_succeeds_with_id(self): resp = self.client.get_file_version_details(self.file_id, self.version_id) mock_response_metadata = { "headers": { - "Content-Type": "text/plain, application/json", + "Content-Type": "application/json", "Authorization": "Basic ZmFrZTEyMjo=", }, "http_status_code": 200, @@ -2471,7 +2471,7 @@ def test_delete_file_version_succeeds(self) -> None: mock_response_metadata = { "headers": { - "Content-Type": "text/plain, application/json", + "Content-Type": "application/json", "Accept-Encoding": "gzip, deflate", "Authorization": "Basic ZmFrZTEyMjo=", }, @@ -2546,7 +2546,7 @@ def test_copy_file_succeeds(self) -> None: mock_response_metadata = { "headers": { - "Content-Type": "text/plain, application/json", + "Content-Type": "application/json", "Accept-Encoding": "gzip, deflate", "Authorization": "Basic ZmFrZTEyMjo=", }, @@ -2592,7 +2592,7 @@ def test_copy_file_succeeds_without_include_file_versions(self) -> None: mock_response_metadata = { "headers": { - "Content-Type": "text/plain, application/json", + "Content-Type": "application/json", "Accept-Encoding": "gzip, deflate", "Authorization": "Basic ZmFrZTEyMjo=", }, @@ -2673,7 +2673,7 @@ def test_move_file_succeeds(self) -> None: ) mock_response_metadata = { "headers": { - "Content-Type": "text/plain, application/json", + "Content-Type": "application/json", "Accept-Encoding": "gzip, deflate", "Authorization": "Basic ZmFrZTEyMjo=", }, @@ -2763,7 +2763,7 @@ def test_rename_file_succeeds_with_purge_cache_false(self) -> None: mock_response_metadata = { "headers": { - "Content-Type": "text/plain, application/json", + "Content-Type": "application/json", "Accept-Encoding": "gzip, deflate", "Authorization": "Basic ZmFrZTEyMjo=", }, @@ -2815,7 +2815,7 @@ def test_rename_file_succeeds_with_purge_cache(self) -> None: mock_response_metadata = { "headers": { - "Content-Type": "text/plain, application/json", + "Content-Type": "application/json", "Accept-Encoding": "gzip, deflate", "Authorization": "Basic ZmFrZTEyMjo=", }, @@ -2859,7 +2859,7 @@ def test_rename_file_succeeds(self) -> None: ) mock_response_metadata = { "headers": { - "Content-Type": "text/plain, application/json", + "Content-Type": "application/json", "Accept-Encoding": "gzip, deflate", "Authorization": "Basic ZmFrZTEyMjo=", }, @@ -2966,7 +2966,7 @@ def test_restore_file_version_succeeds(self) -> None: mock_response_metadata = { "headers": { - "Content-Type": "text/plain, application/json", + "Content-Type": "application/json", "Accept-Encoding": "gzip, deflate", "Authorization": "Basic ZmFrZTEyMjo=", }, diff --git a/tests/test_tags_ops.py b/tests/test_tags_ops.py index b2816a1a..1d27818f 100644 --- a/tests/test_tags_ops.py +++ b/tests/test_tags_ops.py @@ -73,7 +73,7 @@ def test_add_tags_succeeds(self): ) mock_response_metadata = { "headers": { - "Content-Type": "text/plain, application/json", + "Content-Type": "application/json", "Authorization": "Basic ZmFrZTEyMjo=", }, "httpStatusCode": 200, @@ -170,7 +170,7 @@ def test_remove_tags_succeeds(self): ) mock_response_metadata = { "headers": { - "Content-Type": "text/plain, application/json", + "Content-Type": "application/json", "Authorization": "Basic ZmFrZTEyMjo=", }, "httpStatusCode": 200, @@ -280,7 +280,7 @@ def test_remove_ai_tags_succeeds(self): ) mock_response_metadata = { "headers": { - "Content-Type": "text/plain, application/json", + "Content-Type": "application/json", "Authorization": "Basic ZmFrZTEyMjo=", }, "httpStatusCode": 200, From 79a18ab73df7e5bb81b345c539545ab186b3b52a Mon Sep 17 00:00:00 2001 From: Abhinav Dhiman Date: Mon, 1 Sep 2025 15:03:27 +0530 Subject: [PATCH 18/26] chore(ci): disable fail fast --- .github/workflows/test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 19c362fb..773ed9fb 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -6,6 +6,7 @@ jobs: build: runs-on: ubuntu-22.04 strategy: + fail-fast: false matrix: python: [3.7, 3.8, 3.9, '3.10', '3.11', '3.12', '3.13'] urllib3-line: ["lt2", "ge2"] From bb1a41b1aaff7070680896ad3e761166f4235357 Mon Sep 17 00:00:00 2001 From: Abhinav Dhiman Date: Mon, 1 Sep 2025 15:07:57 +0530 Subject: [PATCH 19/26] refactor: consolidate urllib3 version constraints into single global requirement --- requirements/requirements.txt | 6 ++---- requirements/test.txt | 4 +--- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/requirements/requirements.txt b/requirements/requirements.txt index 4bf508c7..ee3399c1 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -1,13 +1,11 @@ requests_toolbelt>=1.0.0 +urllib3<3 # ------------ Python >= 3.9 ------------ requests>=2.32.2; python_version >= "3.9" -urllib3<3; python_version >= "3.9" # ------------ 3.7 <= Python < 3.9 ------------ requests>=2.22.0,<2.32; python_version >= "3.7" and python_version < "3.9" -urllib3<2; python_version >= "3.7" and python_version < "3.9" # ------------ Python < 3.7 ------------ -requests>=2.22.0,<2.28; python_version < "3.7" -urllib3<2; python_version < "3.7" \ No newline at end of file +requests>=2.22.0,<2.28; python_version < "3.7" \ No newline at end of file diff --git a/requirements/test.txt b/requirements/test.txt index e2291fbe..3fdbe29a 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -1,19 +1,17 @@ requests_toolbelt>=1.0.0 +urllib3<3 # ------------ Python >= 3.9 ------------ requests>=2.32.2; python_version >= "3.9" -urllib3<3; python_version >= "3.9" coverage>=7.6.0; python_version >= "3.13" coverage>=7.5.0; python_version >= "3.9" and python_version < "3.13" # ------------ 3.7 <= Python < 3.9 ------------ requests>=2.22.0,<2.32; python_version >= "3.7" and python_version < "3.9" -urllib3<2; python_version >= "3.7" and python_version < "3.9" coverage>=5.0,<7.0; python_version >= "3.7" and python_version < "3.9" # ------------ Python < 3.7 ------------ requests>=2.22.0,<2.28; python_version < "3.7" -urllib3<2; python_version < "3.7" coverage==4.5.4; python_version < "3.7" # ------------ responses versions ------------ From 37d611761f2970692971d7b6f47335536ae39e16 Mon Sep 17 00:00:00 2001 From: Abhinav Dhiman Date: Mon, 1 Sep 2025 15:43:50 +0530 Subject: [PATCH 20/26] tweak: add Content-Type header to test request headers --- tests/helpers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/helpers.py b/tests/helpers.py index 62fb542f..1f54bf6e 100644 --- a/tests/helpers.py +++ b/tests/helpers.py @@ -51,7 +51,7 @@ def setUp(self, mock_file, mock_req): def create_headers_for_test(): - headers = {"Accept-Encoding": "gzip, deflate"} + headers = {"Accept-Encoding": "gzip, deflate", "Content-Type": "application/json"} headers.update(get_auth_headers_for_test()) return headers From f71389c7fdfe9f0e999fef3dbb5d2b7a629873f4 Mon Sep 17 00:00:00 2001 From: Abhinav Dhiman Date: Mon, 1 Sep 2025 16:02:49 +0530 Subject: [PATCH 21/26] Revert "tweak: add Content-Type header to test request headers" This reverts commit 37d611761f2970692971d7b6f47335536ae39e16. --- tests/helpers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/helpers.py b/tests/helpers.py index 1f54bf6e..62fb542f 100644 --- a/tests/helpers.py +++ b/tests/helpers.py @@ -51,7 +51,7 @@ def setUp(self, mock_file, mock_req): def create_headers_for_test(): - headers = {"Accept-Encoding": "gzip, deflate", "Content-Type": "application/json"} + headers = {"Accept-Encoding": "gzip, deflate"} headers.update(get_auth_headers_for_test()) return headers From a82ec0a1ec19e9e82949e74f368e2f8ea6ae5998 Mon Sep 17 00:00:00 2001 From: Abhinav Dhiman Date: Mon, 1 Sep 2025 16:42:57 +0530 Subject: [PATCH 22/26] fix: add missing content_type="application/json" to API test responses --- tests/test_custom_metadata_fields_ops.py | 7 +++++++ tests/test_files_ops.py | 19 ++++++++++++++----- tests/test_tags_ops.py | 3 +++ 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/tests/test_custom_metadata_fields_ops.py b/tests/test_custom_metadata_fields_ops.py index e5084933..9a6931e2 100644 --- a/tests/test_custom_metadata_fields_ops.py +++ b/tests/test_custom_metadata_fields_ops.py @@ -392,6 +392,7 @@ def test_create_custom_metadata_fields_succeeds_with_type_number(self): url, status=201, headers=headers, + content_type="application/json", body="""{ "id": "62dfc03b1b02a58936efca37", "name": "test", @@ -464,6 +465,7 @@ def test_create_custom_metadata_fields_succeeds_with_type_textarea(self): url, status=201, headers=headers, + content_type="application/json", body="""{ "id": "62e0d7ae1b02a589360dc1fd", "name": "test", @@ -550,6 +552,7 @@ def test_create_custom_metadata_fields_succeeds_with_type_date(self): url, status=201, headers=headers, + content_type="application/json", body="""{ "id": "62dfc9f41b02a58936f0d284", "name": "test-date", @@ -628,6 +631,7 @@ def test_create_custom_metadata_fields_succeeds_with_type_boolean(self): url, status=201, headers=headers, + content_type="application/json", body="""{ "id": "62dfcb801b02a58936f0fc39", "name": "test-boolean", @@ -706,6 +710,7 @@ def test_create_custom_metadata_fields_succeeds_with_type_single_select(self): url, status=201, headers=headers, + content_type="application/json", body="""{ "id": "62dfcdb21b02a58936f14c97", "name": "test", @@ -782,6 +787,7 @@ def test_create_custom_metadata_fields_succeeds_with_type_multi_select(self): url, status=201, headers=headers, + content_type="application/json", body="""{ "id": "62dfcf001b02a58936f17808", "name": "test", @@ -863,6 +869,7 @@ def test_update_custom_metadata_fields_succeeds(self): responses.PATCH, url, headers=headers, + content_type="application/json", body="""{ "id": "62a9d5f6db485107347bb7f2", "name": "test", diff --git a/tests/test_files_ops.py b/tests/test_files_ops.py index 29a7aaf0..7a9930a1 100644 --- a/tests/test_files_ops.py +++ b/tests/test_files_ops.py @@ -1163,6 +1163,7 @@ def test_bulk_file_delete_succeeds(self): url, body='{"successfullyDeletedFileIds": ["fake_123", "fake_222"]}', headers=headers, + content_type="application/json", ) resp = self.client.bulk_file_delete(self.bulk_delete_ids) @@ -1204,6 +1205,7 @@ def test_bulk_file_delete_succeeds_and_recieves_extra_non_breaking_changes_from_ url, body='{"successfullyDeletedFileIds": ["fake_123"],"nonDeletedFields":["fake_222"]}', headers=headers, + content_type="application/json", ) resp = self.client.bulk_file_delete(self.bulk_delete_ids) @@ -1298,7 +1300,7 @@ def test_file_delete_succeeds(self): headers = {"Content-Type": "application/json"} headers.update(get_auth_headers_for_test()) - responses.add(responses.DELETE, url , status=204, headers=headers) + responses.add(responses.DELETE, url , status=204, headers=headers, content_type="application/json") resp = self.client.delete_file(self.file_id) @@ -1659,6 +1661,7 @@ def test_update_file_details_succeeds_with_id(self): responses.add( responses.PATCH, url, + content_type="application/json", body="""{ "type": "file", "name": "default-image.jpg", @@ -1820,6 +1823,7 @@ def test_update_file_publish_status_succeeds_(self): responses.add( responses.PATCH, url, + content_type="application/json", body="""{ "type": "file", "name": "default-image.jpg", @@ -2033,6 +2037,7 @@ def test_get_file_versions_succeeds_with_id(self): responses.add( responses.GET, url, + content_type="application/json", body="""[{ "type": "file", "name": "new_car.jpg", @@ -2334,6 +2339,7 @@ def test_get_file_version_details_succeeds_with_id(self): "mime": "image/jpeg" }""", headers=headers, + content_type="application/json", ) resp = self.client.get_file_version_details(self.file_id, self.version_id) mock_response_metadata = { @@ -2466,7 +2472,7 @@ def test_delete_file_version_succeeds(self) -> None: ) headers = {"Content-Type": "application/json"} headers.update(create_headers_for_test()) - responses.add(responses.DELETE, url, status=204, headers=headers ) + responses.add(responses.DELETE, url, status=204, headers=headers, content_type="application/json") resp = self.client.delete_file_version(self.file_id, self.version_id) mock_response_metadata = { @@ -2534,7 +2540,7 @@ def test_copy_file_succeeds(self) -> None: url = "{}/v1/files/copy".format(URL.API_BASE_URL) headers = {"Content-Type": "application/json"} headers.update(create_headers_for_test()) - responses.add(responses.POST, url, status=204, headers=headers) + responses.add(responses.POST, url, status=204, headers=headers, content_type="application/json") resp = self.client.copy_file( options=CopyFileRequestOptions( @@ -2581,7 +2587,7 @@ def test_copy_file_succeeds_without_include_file_versions(self) -> None: url = "{}/v1/files/copy".format(URL.API_BASE_URL) headers = {"Content-Type": "application/json"} headers.update(create_headers_for_test()) - responses.add(responses.POST, url, status=204, headers=headers ) + responses.add(responses.POST, url, status=204, headers=headers, content_type="application/json") resp = self.client.copy_file( options=CopyFileRequestOptions( @@ -2663,7 +2669,7 @@ def test_move_file_succeeds(self) -> None: url = "{}/v1/files/move".format(URL.API_BASE_URL) headers = {"Content-Type": "application/json"} headers.update(create_headers_for_test()) - responses.add(responses.POST, url, status=204, headers=headers ) + responses.add(responses.POST, url, status=204, headers=headers, content_type="application/json") resp = self.client.move_file( options=MoveFileRequestOptions( @@ -2752,6 +2758,7 @@ def test_rename_file_succeeds_with_purge_cache_false(self) -> None: url, headers=headers, body="{}", + content_type="application/json", ) resp = self.client.rename_file( options=RenameFileRequestOptions( @@ -2804,6 +2811,7 @@ def test_rename_file_succeeds_with_purge_cache(self) -> None: url, headers=headers, body='{"purgeRequestId": "62de3e986f68334a5a3339fb"}', + content_type="application/json", ) resp = self.client.rename_file( options=RenameFileRequestOptions( @@ -2927,6 +2935,7 @@ def test_restore_file_version_succeeds(self) -> None: responses.PUT, url, headers=headers, + content_type="application/json", body="""{ "fileId": "fileId", "type": "file", diff --git a/tests/test_tags_ops.py b/tests/test_tags_ops.py index 1d27818f..96a350c6 100644 --- a/tests/test_tags_ops.py +++ b/tests/test_tags_ops.py @@ -66,6 +66,7 @@ def test_add_tags_succeeds(self): url, body='{"successfullyUpdatedFileIds": ["fake_123"]}', headers=headers, + content_type="application/json", ) resp = self.client.add_tags( @@ -163,6 +164,7 @@ def test_remove_tags_succeeds(self): url, body='{"successfullyUpdatedFileIds": ["fake_123"]}', headers=headers, + content_type="application/json", ) resp = self.client.remove_tags( @@ -273,6 +275,7 @@ def test_remove_ai_tags_succeeds(self): url, body='{"successfullyUpdatedFileIds": ["fake_123"]}', headers=headers, + content_type="application/json", ) resp = self.client.remove_ai_tags( From 76fc1bc7d30db4ed8bb72082a033df26eebc7270 Mon Sep 17 00:00:00 2001 From: Abhinav Dhiman Date: Mon, 1 Sep 2025 16:55:41 +0530 Subject: [PATCH 23/26] fix: remove redundant Content-Type headers and standardize response content types to application/json --- tests/test_custom_metadata_fields_ops.py | 17 ++++----- tests/test_files_ops.py | 44 ++++++++++++------------ tests/test_tags_ops.py | 12 +++---- 3 files changed, 37 insertions(+), 36 deletions(-) diff --git a/tests/test_custom_metadata_fields_ops.py b/tests/test_custom_metadata_fields_ops.py index 9a6931e2..0e43a957 100644 --- a/tests/test_custom_metadata_fields_ops.py +++ b/tests/test_custom_metadata_fields_ops.py @@ -62,6 +62,7 @@ def test_get_custom_metadata_fields_succeeds(self): responses.add( responses.GET, url, + content_type="application/json", body="""[{ "id": "62a9d5f6db485107347bb7f2", "name": "test10", @@ -115,7 +116,7 @@ def test_get_custom_metadata_fields_succeeds(self): ], "httpStatusCode": 200, "headers": { - "Content-Type": "text/plain", + "Content-Type": "application/json", "Accept-Encoding": "gzip, deflate", "Authorization": "Basic ZmFrZTEyMjo=", }, @@ -385,7 +386,7 @@ def test_create_custom_metadata_fields_succeeds_with_type_number(self): """ URL.API_BASE_URL = "http://test.com" url = "{}/v1/customMetadataFields".format(URL.API_BASE_URL) - headers = {"Content-Type": "application/json"} + headers = {} headers.update(create_headers_for_test()) responses.add( responses.POST, @@ -458,7 +459,7 @@ def test_create_custom_metadata_fields_succeeds_with_type_textarea(self): """ URL.API_BASE_URL = "http://test.com" url = "{}/v1/customMetadataFields".format(URL.API_BASE_URL) - headers = {"Content-Type": "application/json"} + headers = {} headers.update(create_headers_for_test()) responses.add( responses.POST, @@ -545,7 +546,7 @@ def test_create_custom_metadata_fields_succeeds_with_type_date(self): """ URL.API_BASE_URL = "http://test.com" url = "{}/v1/customMetadataFields".format(URL.API_BASE_URL) - headers = {"Content-Type": "application/json"} + headers = {} headers.update(create_headers_for_test()) responses.add( responses.POST, @@ -624,7 +625,7 @@ def test_create_custom_metadata_fields_succeeds_with_type_boolean(self): """ URL.API_BASE_URL = "http://test.com" url = "{}/v1/customMetadataFields".format(URL.API_BASE_URL) - headers = {"Content-Type": "application/json"} + headers = {} headers.update(create_headers_for_test()) responses.add( responses.POST, @@ -703,7 +704,7 @@ def test_create_custom_metadata_fields_succeeds_with_type_single_select(self): """ URL.API_BASE_URL = "http://test.com" url = "{}/v1/customMetadataFields".format(URL.API_BASE_URL) - headers = {"Content-Type": "application/json"} + headers = {} headers.update(create_headers_for_test()) responses.add( responses.POST, @@ -780,7 +781,7 @@ def test_create_custom_metadata_fields_succeeds_with_type_multi_select(self): """ URL.API_BASE_URL = "http://test.com" url = "{}/v1/customMetadataFields".format(URL.API_BASE_URL) - headers = {"Content-Type": "application/json"} + headers = {} headers.update(create_headers_for_test()) responses.add( responses.POST, @@ -863,7 +864,7 @@ def test_update_custom_metadata_fields_succeeds(self): """ URL.API_BASE_URL = "http://test.com" url = "{}/v1/customMetadataFields/{}".format(URL.API_BASE_URL, self.field_id) - headers = {"Content-Type": "application/json"} + headers = {} headers.update(create_headers_for_test()) responses.add( responses.PATCH, diff --git a/tests/test_files_ops.py b/tests/test_files_ops.py index 7a9930a1..ed7d6600 100644 --- a/tests/test_files_ops.py +++ b/tests/test_files_ops.py @@ -1155,7 +1155,7 @@ def test_bulk_file_delete_succeeds(self): URL.API_BASE_URL = "http://test.com" url = URL.API_BASE_URL + "/v1/files" + URL.BULK_FILE_DELETE - headers = {"Content-Type": "application/json"} + headers = {} headers.update(get_auth_headers_for_test()) responses.add( @@ -1197,7 +1197,7 @@ def test_bulk_file_delete_succeeds_and_recieves_extra_non_breaking_changes_from_ URL.API_BASE_URL = "http://test.com" url = URL.API_BASE_URL + "/v1/files" + URL.BULK_FILE_DELETE - headers = {"Content-Type": "application/json"} + headers = {} headers.update(get_auth_headers_for_test()) responses.add( @@ -1237,7 +1237,7 @@ def test_bulk_file_delete_fails_with_404_exception(self) -> None: URL.API_BASE_URL = "http://test.com" url = URL.API_BASE_URL + "/v1/files" + URL.BULK_FILE_DELETE - headers = {"Content-Type": "application/json"} + headers = {} headers.update(get_auth_headers_for_test()) try: responses.add( @@ -1269,7 +1269,7 @@ def test_file_delete_fails_with_400_exception(self): URL.API_BASE_URL = "http://test.com" url = "{}/v1/files/{}".format(URL.API_BASE_URL, self.file_id) - headers = {"Content-Type": "application/json"} + headers = {} headers.update(get_auth_headers_for_test()) try: responses.add( @@ -1297,7 +1297,7 @@ def test_file_delete_succeeds(self): """ URL.API_BASE_URL = "http://test.com" url = "{}/v1/files/{}".format(URL.API_BASE_URL, self.file_id) - headers = {"Content-Type": "application/json"} + headers = {} headers.update(get_auth_headers_for_test()) responses.add(responses.DELETE, url , status=204, headers=headers, content_type="application/json") @@ -1656,7 +1656,7 @@ def test_update_file_details_succeeds_with_id(self): """ URL.API_BASE_URL = "http://test.com" url = "{}/v1/files/{}/details/".format(URL.API_BASE_URL, self.file_id) - headers = {"Content-Type": "application/json"} + headers = {} headers.update(get_auth_headers_for_test()) responses.add( responses.PATCH, @@ -1818,7 +1818,7 @@ def test_update_file_publish_status_succeeds_(self): """ URL.API_BASE_URL = "http://test.com" url = "{}/v1/files/{}/details/".format(URL.API_BASE_URL, self.file_id) - headers = {"Content-Type": "application/json"} + headers = {} headers.update(get_auth_headers_for_test()) responses.add( responses.PATCH, @@ -2032,7 +2032,7 @@ def test_get_file_versions_succeeds_with_id(self): URL.API_BASE_URL = "http://test.com" url = "{}/v1/files/{}/versions".format(URL.API_BASE_URL, self.file_id) - headers = {"Content-Type": "application/json"} + headers = {} headers.update(get_auth_headers_for_test()) responses.add( responses.GET, @@ -2300,7 +2300,7 @@ def test_get_file_version_details_succeeds_with_id(self): URL.API_BASE_URL, self.file_id, self.version_id ) - headers = {"Content-Type": "application/json"} + headers = {} headers.update(get_auth_headers_for_test()) responses.add( responses.GET, @@ -2470,7 +2470,7 @@ def test_delete_file_version_succeeds(self) -> None: url = "{}/v1/files/{}/versions/{}".format( URL.API_BASE_URL, self.file_id, self.version_id ) - headers = {"Content-Type": "application/json"} + headers = {} headers.update(create_headers_for_test()) responses.add(responses.DELETE, url, status=204, headers=headers, content_type="application/json") resp = self.client.delete_file_version(self.file_id, self.version_id) @@ -2506,7 +2506,7 @@ def test_copy_file_fails_with_404(self) -> None: URL.API_BASE_URL = "http://test.com" url = "{}/v1/files/copy".format(URL.API_BASE_URL) - headers = {"Content-Type": "application/json"} + headers = {} headers.update(create_headers_for_test()) responses.add( responses.POST, @@ -2538,7 +2538,7 @@ def test_copy_file_succeeds(self) -> None: URL.API_BASE_URL = "http://test.com" url = "{}/v1/files/copy".format(URL.API_BASE_URL) - headers = {"Content-Type": "application/json"} + headers = {} headers.update(create_headers_for_test()) responses.add(responses.POST, url, status=204, headers=headers, content_type="application/json") @@ -2585,7 +2585,7 @@ def test_copy_file_succeeds_without_include_file_versions(self) -> None: URL.API_BASE_URL = "http://test.com" url = "{}/v1/files/copy".format(URL.API_BASE_URL) - headers = {"Content-Type": "application/json"} + headers = {} headers.update(create_headers_for_test()) responses.add(responses.POST, url, status=204, headers=headers, content_type="application/json") @@ -2636,7 +2636,7 @@ def test_move_file_fails_with_404(self) -> None: URL.API_BASE_URL = "http://test.com" url = "{}/v1/files/move".format(URL.API_BASE_URL) - headers = {"Content-Type": "application/json"} + headers = {} headers.update(create_headers_for_test()) responses.add( responses.POST, @@ -2667,7 +2667,7 @@ def test_move_file_succeeds(self) -> None: URL.API_BASE_URL = "http://test.com" url = "{}/v1/files/move".format(URL.API_BASE_URL) - headers = {"Content-Type": "application/json"} + headers = {} headers.update(create_headers_for_test()) responses.add(responses.POST, url, status=204, headers=headers, content_type="application/json") @@ -2717,7 +2717,7 @@ def test_rename_file_fails_with_409(self) -> None: URL.API_BASE_URL = "http://test.com" url = "{}/v1/files/rename".format(URL.API_BASE_URL) - headers = {"Content-Type": "application/json"} + headers = {} headers.update(create_headers_for_test()) try: responses.add( @@ -2751,7 +2751,7 @@ def test_rename_file_succeeds_with_purge_cache_false(self) -> None: URL.API_BASE_URL = "http://test.com" url = "{}/v1/files/rename".format(URL.API_BASE_URL) - headers = {"Content-Type": "application/json"} + headers = {} headers.update(create_headers_for_test()) responses.add( responses.PUT, @@ -2804,7 +2804,7 @@ def test_rename_file_succeeds_with_purge_cache(self) -> None: URL.API_BASE_URL = "http://test.com" url = "{}/v1/files/rename".format(URL.API_BASE_URL) - headers = {"Content-Type": "application/json"} + headers = {} headers.update(create_headers_for_test()) responses.add( responses.PUT, @@ -2857,9 +2857,9 @@ def test_rename_file_succeeds(self) -> None: URL.API_BASE_URL = "http://test.com" url = "{}/v1/files/rename".format(URL.API_BASE_URL) - headers = {"Content-Type": "application/json"} + headers = {} headers.update(create_headers_for_test()) - responses.add(responses.PUT, url, headers=headers, body="{}") + responses.add(responses.PUT, url, headers=headers, body="{}", content_type="application/json") resp = self.client.rename_file( options=RenameFileRequestOptions( file_path=self.file_path, new_file_name=self.new_file_name @@ -2929,7 +2929,7 @@ def test_restore_file_version_succeeds(self) -> None: url = "{}/v1/files/{}/versions/{}/restore".format( URL.API_BASE_URL, self.file_id, self.version_id ) - headers = {"Content-Type": "application/json"} + headers = {} headers.update(create_headers_for_test()) responses.add( responses.PUT, @@ -3018,7 +3018,7 @@ def test_restore_file_version_succeeds(self) -> None: def test_get_metadata_with_non_breaking_changes_in_response(self): URL.API_BASE_URL = "http://test.com" url = "{}/v1/files/{}/metadata".format(URL.API_BASE_URL, self.file_id) - headers = {"Content-Type": "application/json"} + headers = {} headers.update(create_headers_for_test()) responses.add( responses.GET, diff --git a/tests/test_tags_ops.py b/tests/test_tags_ops.py index 96a350c6..a7945cd0 100644 --- a/tests/test_tags_ops.py +++ b/tests/test_tags_ops.py @@ -59,7 +59,7 @@ def test_add_tags_succeeds(self): """ URL.API_BASE_URL = "http://test.com" url = "{}/v1/files/addTags".format(URL.API_BASE_URL) - headers = {"Content-Type": "application/json"} + headers = {} headers.update(get_auth_headers_for_test()) responses.add( responses.POST, @@ -104,7 +104,7 @@ def test_add_tags_fails_with_404_exception(self) -> None: URL.API_BASE_URL = "http://test.com" url = "{}/v1/files/addTags".format(URL.API_BASE_URL) - headers = {"Content-Type": "application/json"} + headers = {} headers.update(get_auth_headers_for_test()) try: responses.add( @@ -157,7 +157,7 @@ def test_remove_tags_succeeds(self): """ URL.API_BASE_URL = "http://test.com" url = "{}/v1/files/removeTags".format(URL.API_BASE_URL) - headers = {"Content-Type": "application/json"} + headers = {} headers.update(get_auth_headers_for_test()) responses.add( responses.POST, @@ -202,7 +202,7 @@ def test_remove_tags_fails_with_404_exception(self) -> None: URL.API_BASE_URL = "http://test.com" url = "{}/v1/files/removeTags".format(URL.API_BASE_URL) - headers = {"Content-Type": "application/json"} + headers = {} headers.update(get_auth_headers_for_test()) try: responses.add( @@ -268,7 +268,7 @@ def test_remove_ai_tags_succeeds(self): """ URL.API_BASE_URL = "http://test.com" url = "{}/v1/files/removeAITags".format(URL.API_BASE_URL) - headers = {"Content-Type": "application/json"} + headers = {} headers.update(get_auth_headers_for_test()) responses.add( responses.POST, @@ -313,7 +313,7 @@ def test_remove_ai_tags_fails_with_404_exception(self) -> None: URL.API_BASE_URL = "http://test.com" url = "{}/v1/files/removeAITags".format(URL.API_BASE_URL) - headers = {"Content-Type": "application/json"} + headers = {} headers.update(get_auth_headers_for_test()) try: responses.add( From 334fd8f54389e578ddab0527158bde072efe9d36 Mon Sep 17 00:00:00 2001 From: Abhinav Dhiman Date: Mon, 1 Sep 2025 17:26:20 +0530 Subject: [PATCH 24/26] ci: split publish workflow into build and release jobs --- .github/workflows/publish.yml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index ca2c3de2..31b31c7d 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -5,7 +5,7 @@ on: types: [published] jobs: - deploy: + build: runs-on: ubuntu-22.04 strategy: matrix: @@ -18,7 +18,7 @@ jobs: urllib3-line: "ge2" steps: - uses: actions/checkout@v5 - - name: Set up Python + - name: Setup Python uses: actions/setup-python@v5 with: python-version: ${{ matrix.python }} @@ -37,6 +37,14 @@ jobs: pip install -r requirements/test.txt - name: Run Tox run: tox -e py + release: + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v5 + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: 3.12 - name: Install build dependencies run: | pip install setuptools wheel twine From a68a3682b1da97651d7af655a64d9b277cf178cb Mon Sep 17 00:00:00 2001 From: Abhinav Dhiman Date: Mon, 1 Sep 2025 17:49:21 +0530 Subject: [PATCH 25/26] chore: reorganize Python version-specific dependencies and remove redundant entries --- requirements/requirements.txt | 9 +++------ requirements/test.txt | 14 +++++--------- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/requirements/requirements.txt b/requirements/requirements.txt index ee3399c1..13342e00 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -1,11 +1,8 @@ requests_toolbelt>=1.0.0 -urllib3<3 -# ------------ Python >= 3.9 ------------ -requests>=2.32.2; python_version >= "3.9" +urllib3<3; python_version >= "3.9" +urllib3!=2.0.0,<3; python_version < "3.9" -# ------------ 3.7 <= Python < 3.9 ------------ +requests>=2.32.2; python_version >= "3.9" requests>=2.22.0,<2.32; python_version >= "3.7" and python_version < "3.9" - -# ------------ Python < 3.7 ------------ requests>=2.22.0,<2.28; python_version < "3.7" \ No newline at end of file diff --git a/requirements/test.txt b/requirements/test.txt index 3fdbe29a..7df3a74b 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -1,20 +1,16 @@ requests_toolbelt>=1.0.0 -urllib3<3 +urllib3<3; python_version >= "3.9" +urllib3!=2.0.0,<3; python_version < "3.9" -# ------------ Python >= 3.9 ------------ requests>=2.32.2; python_version >= "3.9" +requests>=2.22.0,<2.32; python_version >= "3.7" and python_version < "3.9" +requests>=2.22.0,<2.28; python_version < "3.7" + coverage>=7.6.0; python_version >= "3.13" coverage>=7.5.0; python_version >= "3.9" and python_version < "3.13" - -# ------------ 3.7 <= Python < 3.9 ------------ -requests>=2.22.0,<2.32; python_version >= "3.7" and python_version < "3.9" coverage>=5.0,<7.0; python_version >= "3.7" and python_version < "3.9" - -# ------------ Python < 3.7 ------------ -requests>=2.22.0,<2.28; python_version < "3.7" coverage==4.5.4; python_version < "3.7" -# ------------ responses versions ------------ responses>=0.25.0; python_version >= "3.8" responses>=0.18.0,<0.25; python_version >= "3.7" and python_version < "3.8" responses<0.18.0; python_version < "3.7" From 4061f87b3ad1c807b5b79bfcfbcc254f2d188fd1 Mon Sep 17 00:00:00 2001 From: Abhinav Dhiman Date: Fri, 12 Sep 2025 11:44:54 +0530 Subject: [PATCH 26/26] chore: bump version from 4.1.0 to 4.2.0 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 084fabec..c5df52a9 100644 --- a/setup.py +++ b/setup.py @@ -8,7 +8,7 @@ setuptools.setup( name="imagekitio", - version="4.1.0", + version="4.2.0", description="Python wrapper for the ImageKit API", long_description=long_description, long_description_content_type="text/markdown",