From 88e1caec367dfaab7383a7c110a1d45b0b52c0cf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 20 Aug 2026 11:10:53 +0000 Subject: [PATCH 1/3] Bump werkzeug from 2.2.2 to 3.1.6 in /api Bumps [werkzeug](https://github.com/pallets/werkzeug) from 2.2.2 to 3.1.6. - [Release notes](https://github.com/pallets/werkzeug/releases) - [Changelog](https://github.com/pallets/werkzeug/blob/main/CHANGES.rst) - [Commits](https://github.com/pallets/werkzeug/compare/2.2.2...3.1.6) --- updated-dependencies: - dependency-name: werkzeug dependency-version: 3.1.6 dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- api/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/requirements.txt b/api/requirements.txt index 4779919..16632a4 100644 --- a/api/requirements.txt +++ b/api/requirements.txt @@ -1,6 +1,6 @@ Flask==2.2.2 gunicorn -Werkzeug==2.2.2 +Werkzeug==3.1.6 azure-monitor-opentelemetry==1.8.7 azure-identity==1.17.1 azure-mgmt-compute==33.0.0 From 6c44beb2a36053d5f51b42c3e5f605ddeca1ccde Mon Sep 17 00:00:00 2001 From: Paul Lizer Date: Thu, 20 Aug 2026 08:16:31 -0400 Subject: [PATCH 2/3] Bump Werkzeug to 3.1.8 and refresh/pin all Python dependencies The Dependabot change bumped Werkzeug 2.2.2 -> 3.1.6 in /api but left Flask==2.2.2 in place. Flask 2.2.2 does `from werkzeug.urls import url_quote` at module scope, and url_quote was removed in Werkzeug 3.0. Flask 2.2.2 declares `Werkzeug>=2.2.2` with no upper bound, so pip resolves it and the image builds -- then gunicorn dies at startup with: ImportError: cannot import name 'url_quote' from 'werkzeug.urls' The only workflow triggers on pushes to prod-changes rather than on pull requests, so this would not have been caught before deploy. api: Flask 2.2.2 -> 3.1.3, Werkzeug 3.1.6 -> 3.1.8, gunicorn now pinned, and Azure SDK / requests / cryptography / pyjwt / flask-caching refreshed. front_end: Same Flask/Werkzeug bump (it was still entirely on 2.2.2 and shared the latent break), plus Flask-WTF 1.2.1 -> 1.3.0. task: Previously unpinned deps are now pinned, and `azure.identity` is normalised to `azure-identity`. azure-functions is held at 1.25.0 because 2.x requires Python >=3.13 while the image is python3.11. dev: pytest 9.1.1 for both services, PyYAML 6.0.3. Verified: 122 tests pass (44 api, 78 front_end); all three services build on their real base images for linux/python3.11 and boot under gunicorn -- front_end returns 200 on /health and /favicon.ico (exercising send_from_directory, the safe_join CVE surface), api returns a clean 503 on /health without a database and 404s unknown routes. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- api/requirements-dev.txt | 4 ++-- api/requirements.txt | 24 ++++++++++++------------ front_end/requirements-dev.txt | 2 +- front_end/requirements.txt | 12 ++++++------ task/requirements.txt | 6 +++--- 5 files changed, 24 insertions(+), 24 deletions(-) diff --git a/api/requirements-dev.txt b/api/requirements-dev.txt index 5acec5d..f162d39 100644 --- a/api/requirements-dev.txt +++ b/api/requirements-dev.txt @@ -1,2 +1,2 @@ -pytest==8.3.4 -PyYAML==6.0.2 +pytest==9.1.1 +PyYAML==6.0.3 diff --git a/api/requirements.txt b/api/requirements.txt index 16632a4..2e47662 100644 --- a/api/requirements.txt +++ b/api/requirements.txt @@ -1,12 +1,12 @@ -Flask==2.2.2 -gunicorn -Werkzeug==3.1.6 -azure-monitor-opentelemetry==1.8.7 -azure-identity==1.17.1 -azure-mgmt-compute==33.0.0 -pyjwt==2.9.0 -cryptography==43.0.3 -requests==2.26.0 -flask_caching==2.3.0 -pymssql==2.3.1 -azure-keyvault-secrets==4.9.0 \ No newline at end of file +Flask==3.1.3 +gunicorn==26.0.0 +Werkzeug==3.1.8 +azure-monitor-opentelemetry==1.8.9 +azure-identity==1.25.3 +azure-mgmt-compute==38.3.0 +pyjwt==2.13.0 +cryptography==50.0.0 +requests==2.34.2 +flask_caching==2.4.1 +pymssql==2.3.13 +azure-keyvault-secrets==4.11.1 \ No newline at end of file diff --git a/front_end/requirements-dev.txt b/front_end/requirements-dev.txt index b3b2b3c..7345f25 100644 --- a/front_end/requirements-dev.txt +++ b/front_end/requirements-dev.txt @@ -1 +1 @@ -pytest==9.0.3 +pytest==9.1.1 diff --git a/front_end/requirements.txt b/front_end/requirements.txt index d1b300f..d38f71a 100644 --- a/front_end/requirements.txt +++ b/front_end/requirements.txt @@ -1,10 +1,10 @@ -Flask==2.2.2 -gunicorn -Werkzeug==2.2.2 -azure-monitor-opentelemetry==1.8.7 -requests==2.26.0 +Flask==3.1.3 +gunicorn==26.0.0 +Werkzeug==3.1.8 +azure-monitor-opentelemetry==1.8.9 +requests==2.34.2 msal==1.37.0 Flask-Session==0.8.0 -Flask-WTF==1.2.1 +Flask-WTF==1.3.0 pyjwt==2.13.0 cryptography==50.0.0 diff --git a/task/requirements.txt b/task/requirements.txt index 3056260..61e8c4a 100644 --- a/task/requirements.txt +++ b/task/requirements.txt @@ -2,6 +2,6 @@ # The Python Worker is managed by Azure Functions platform # Manually managing azure-functions-worker may cause unexpected issues -azure-functions -requests -azure.identity \ No newline at end of file +azure-functions==1.25.0 +requests==2.34.2 +azure-identity==1.25.3 \ No newline at end of file From d2214f546b5d441348dee827f28ca7d80af847cc Mon Sep 17 00:00:00 2001 From: Paul Lizer Date: Thu, 20 Aug 2026 08:35:44 -0400 Subject: [PATCH 3/3] Move all services to Python 3.13 and unlock azure-functions 2.2.0 azure-functions 2.x requires Python >=3.13, which was the reason the task app was held back at azure-functions 1.25.0. Moving the runtime to 3.13 unblocks it. - api/Dockerfile, front_end/Dockerfile: python:3.11-slim -> python:3.13-slim - task/Dockerfile: azure-functions/python:4-python3.11 -> 4-python3.13 - Both workflows (app tests + prod deploy): python-version 3.11 -> 3.13 - task: azure-functions 1.25.0 -> 2.2.0 azure-functions 2.0 carries the same SDK content as 1.25.0b3, so there are no programming-model changes; the only requirements are Python >=3.13 and Functions runtime 4.x. The bicep already sets FUNCTIONS_EXTENSION_VERSION '~4' and the function app is container-deployed, so no infrastructure change is needed. Every other pin was re-resolved against Python 3.13 and was already at the newest version available, so no other requirement changed. Verified on Python 3.13.15: - 122 tests pass (44 api, 78 front_end), run the same way CI does -- a clean `pip install -r requirements.txt -r requirements-dev.txt` on a bare image with no system packages, confirming the cp313 wheels for pymssql and cryptography resolve. - All three images build on their real base images. - api and front_end boot under gunicorn: front_end returns 200 on /health and /favicon.ico, api binds and returns a clean 503 on /health without a database. - task function app loads and registers all 3 timer triggers. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .github/workflows/front-end-tests.yml | 4 ++-- .github/workflows/prod-changes_byavdlinuxbrokerapi.yml | 2 +- api/Dockerfile | 2 +- front_end/Dockerfile | 2 +- task/Dockerfile | 2 +- task/requirements.txt | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/front-end-tests.yml b/.github/workflows/front-end-tests.yml index 522f0ee..ffd648a 100644 --- a/.github/workflows/front-end-tests.yml +++ b/.github/workflows/front-end-tests.yml @@ -24,7 +24,7 @@ jobs: - name: Set up Python version uses: actions/setup-python@v5 with: - python-version: '3.11' + python-version: '3.13' - name: Install dependencies working-directory: front_end @@ -54,7 +54,7 @@ jobs: - name: Set up Python version uses: actions/setup-python@v5 with: - python-version: '3.11' + python-version: '3.13' - name: Install dependencies working-directory: api diff --git a/.github/workflows/prod-changes_byavdlinuxbrokerapi.yml b/.github/workflows/prod-changes_byavdlinuxbrokerapi.yml index d74363d..afb28a6 100644 --- a/.github/workflows/prod-changes_byavdlinuxbrokerapi.yml +++ b/.github/workflows/prod-changes_byavdlinuxbrokerapi.yml @@ -22,7 +22,7 @@ jobs: - name: Set up Python version uses: actions/setup-python@v5 with: - python-version: '3.11' + python-version: '3.13' - name: Create and start virtual environment run: | diff --git a/api/Dockerfile b/api/Dockerfile index 9ea375d..225bc3b 100644 --- a/api/Dockerfile +++ b/api/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.11-slim +FROM python:3.13-slim ENV PYTHONDONTWRITEBYTECODE=1 ENV PYTHONUNBUFFERED=1 diff --git a/front_end/Dockerfile b/front_end/Dockerfile index d413bd0..b79d162 100644 --- a/front_end/Dockerfile +++ b/front_end/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.11-slim +FROM python:3.13-slim ENV PYTHONDONTWRITEBYTECODE=1 ENV PYTHONUNBUFFERED=1 diff --git a/task/Dockerfile b/task/Dockerfile index c092fd2..e9f4f35 100644 --- a/task/Dockerfile +++ b/task/Dockerfile @@ -1,4 +1,4 @@ -FROM mcr.microsoft.com/azure-functions/python:4-python3.11 +FROM mcr.microsoft.com/azure-functions/python:4-python3.13 ENV AzureWebJobsScriptRoot=/home/site/wwwroot \ AzureFunctionsJobHost__Logging__Console__IsEnabled=true diff --git a/task/requirements.txt b/task/requirements.txt index 61e8c4a..8083995 100644 --- a/task/requirements.txt +++ b/task/requirements.txt @@ -2,6 +2,6 @@ # The Python Worker is managed by Azure Functions platform # Manually managing azure-functions-worker may cause unexpected issues -azure-functions==1.25.0 +azure-functions==2.2.0 requests==2.34.2 azure-identity==1.25.3 \ No newline at end of file