Set python 3.14 version where needed
diff --git a/.github/actions/setup-default-test-properties/test-properties.json b/.github/actions/setup-default-test-properties/test-properties.json
index bbdaffb..e3f1d7a 100644
--- a/.github/actions/setup-default-test-properties/test-properties.json
+++ b/.github/actions/setup-default-test-properties/test-properties.json
@@ -1,12 +1,12 @@
 {
   "PythonTestProperties": {
-    "ALL_SUPPORTED_VERSIONS": ["3.10", "3.11", "3.12", "3.13"],
+    "ALL_SUPPORTED_VERSIONS": ["3.10", "3.11", "3.12", "3.13", "3.14"],
     "LOWEST_SUPPORTED": ["3.10"],
-    "HIGHEST_SUPPORTED": ["3.13"],
-    "ESSENTIAL_VERSIONS": ["3.10", "3.13"],
-    "CROSS_LANGUAGE_VALIDATES_RUNNER_PYTHON_VERSIONS": ["3.10", "3.12", "3.13"],
+    "HIGHEST_SUPPORTED": ["3.14"],
+    "ESSENTIAL_VERSIONS": ["3.10", "3.14"],
+    "CROSS_LANGUAGE_VALIDATES_RUNNER_PYTHON_VERSIONS": ["3.10", "3.12", "3.13", "3.14"],
     "CROSS_LANGUAGE_VALIDATES_RUNNER_DATAFLOW_USING_SQL_PYTHON_VERSIONS": ["3.11"],
-    "VALIDATES_CONTAINER_DATAFLOW_PYTHON_VERSIONS": ["3.10", "3.11", "3.12", "3.13"],
+    "VALIDATES_CONTAINER_DATAFLOW_PYTHON_VERSIONS": ["3.10", "3.11", "3.12", "3.13", "3.14"],
     "LOAD_TEST_PYTHON_VERSION": "3.10",
     "CHICAGO_TAXI_EXAMPLE_FLINK_PYTHON_VERSION": "3.10",
     "DEFAULT_INTERPRETER": "python3.10",
diff --git a/.github/workflows/beam_PostCommit_Python_Examples_Dataflow.yml b/.github/workflows/beam_PostCommit_Python_Examples_Dataflow.yml
index e8a4169..4ea8ab0 100644
--- a/.github/workflows/beam_PostCommit_Python_Examples_Dataflow.yml
+++ b/.github/workflows/beam_PostCommit_Python_Examples_Dataflow.yml
@@ -56,7 +56,7 @@
       github.event_name == 'workflow_dispatch' ||
       github.event_name == 'pull_request_target' ||
       github.event.comment.body == 'Run Python Examples_Dataflow'
-    runs-on: [self-hosted, ubuntu-20.04, main]
+    runs-on: [self-hosted, ubuntu-24.04, main]
     timeout-minutes: 180
     strategy:
       matrix:
@@ -74,14 +74,14 @@
         uses: ./.github/actions/setup-environment-action
         with:
           java-version: default
-          python-version: 3.13
+          python-version: 3.14
       - name: Run examplesPostCommit script
         uses: ./.github/actions/gradle-command-self-hosted-action
         with:
           gradle-command: :sdks:python:test-suites:dataflow:examplesPostCommit
           arguments: |
             -PuseWheelDistribution \
-            -PpythonVersion=3.13 \
+            -PpythonVersion=3.14 \
       - name: Archive Python Test Results
         uses: actions/upload-artifact@v4
         if: failure()
diff --git a/.github/workflows/beam_PostCommit_Python_MongoDBIO_IT.yml b/.github/workflows/beam_PostCommit_Python_MongoDBIO_IT.yml
index 8a42cc7..4efa7f4 100644
--- a/.github/workflows/beam_PostCommit_Python_MongoDBIO_IT.yml
+++ b/.github/workflows/beam_PostCommit_Python_MongoDBIO_IT.yml
@@ -56,7 +56,7 @@
       github.event_name == 'workflow_dispatch' ||
       github.event_name == 'pull_request_target' ||
       github.event.comment.body == 'Run Python MongoDBIO_IT'
-    runs-on: [self-hosted, ubuntu-20.04, main]
+    runs-on: [self-hosted, ubuntu-24.04, main]
     timeout-minutes: 100
     strategy:
       matrix:
@@ -74,13 +74,13 @@
         uses: ./.github/actions/setup-environment-action
         with:
           java-version: default
-          python-version: 3.13
+          python-version: 3.14
       - name: Run mongodbioIT script
         uses: ./.github/actions/gradle-command-self-hosted-action
         with:
           gradle-command: :sdks:python:test-suites:direct:py313:mongodbioIT
           arguments: |
-            -PpythonVersion=3.13 \
+            -PpythonVersion=3.14 \
       - name: Archive Python Test Results
         uses: actions/upload-artifact@v4
         if: failure()
diff --git a/.github/workflows/beam_PostCommit_XVR_PythonUsingJavaSQL_Dataflow.yml b/.github/workflows/beam_PostCommit_XVR_PythonUsingJavaSQL_Dataflow.yml
index 789e34e..2c9108e 100644
--- a/.github/workflows/beam_PostCommit_XVR_PythonUsingJavaSQL_Dataflow.yml
+++ b/.github/workflows/beam_PostCommit_XVR_PythonUsingJavaSQL_Dataflow.yml
@@ -55,7 +55,7 @@
       github.event_name == 'pull_request_target' ||
       (github.event_name == 'schedule' && github.repository == 'apache/beam') ||
       github.event.comment.body == 'Run XVR_PythonUsingJavaSQL_Dataflow PostCommit'
-    runs-on: [self-hosted, ubuntu-20.04, main]
+    runs-on: [self-hosted, ubuntu-24.04, main]
     timeout-minutes: 100
     name: ${{ matrix.job_name }} (${{ matrix.job_phrase }})
     strategy:
@@ -73,13 +73,13 @@
       - name: Setup environment
         uses: ./.github/actions/setup-environment-action
         with:
-          python-version: 3.13
+          python-version: 3.14
       - name: run PostCommit XVR PythonUsingJavaSQL Dataflow script
         uses: ./.github/actions/gradle-command-self-hosted-action
         with:
           gradle-command: :runners:google-cloud-dataflow-java:validatesCrossLanguageRunnerPythonUsingSql
           arguments: |
-            -PpythonVersion=3.13 \
+            -PpythonVersion=3.14 \
       - name: Archive Python Test Results
         uses: actions/upload-artifact@v4
         if: failure()
diff --git a/.github/workflows/beam_PostCommit_XVR_PythonUsingJava_Dataflow.yml b/.github/workflows/beam_PostCommit_XVR_PythonUsingJava_Dataflow.yml
index ac51aa5..196b5f7 100644
--- a/.github/workflows/beam_PostCommit_XVR_PythonUsingJava_Dataflow.yml
+++ b/.github/workflows/beam_PostCommit_XVR_PythonUsingJava_Dataflow.yml
@@ -96,4 +96,4 @@
           commit: '${{ env.prsha || env.GITHUB_SHA }}'
           comment_mode: ${{ github.event_name == 'issue_comment'  && 'always' || 'off' }}
           files: '**/pytest*.xml'
-          large_files: true
\ No newline at end of file
+          large_files: true
diff --git a/.github/workflows/beam_PreCommit_Python_PVR_Flink.yml b/.github/workflows/beam_PreCommit_Python_PVR_Flink.yml
index 05603cb..5acde1b 100644
--- a/.github/workflows/beam_PreCommit_Python_PVR_Flink.yml
+++ b/.github/workflows/beam_PreCommit_Python_PVR_Flink.yml
@@ -88,7 +88,7 @@
       (github.event_name == 'schedule' && github.repository == 'apache/beam') ||
       github.event_name == 'workflow_dispatch' ||
       github.event.comment.body == 'Run Python_PVR_Flink PreCommit'
-    runs-on: [self-hosted, ubuntu-20.04, main]
+    runs-on: [self-hosted, ubuntu-24.04, main]
     steps:
       - uses: actions/checkout@v4
       - name: Setup repository
@@ -100,16 +100,16 @@
       - name: Setup environment
         uses: ./.github/actions/setup-environment-action
         with:
-          python-version: 3.13
+          python-version: 3.14
       - name: run Python PVR Flink PreCommit script
         uses: ./.github/actions/gradle-command-self-hosted-action
         env:
           CLOUDSDK_CONFIG: ${{ env.KUBELET_GCLOUD_CONFIG_PATH}}
         with:
           # Run Flink 2 tests. Flink 1.20 is covered by PostCommit_Python_ValidatesRunner_Flink
-          gradle-command: :sdks:python:test-suites:portable:py313:flinkValidatesRunner
+          gradle-command: :sdks:python:test-suites:portable:py314:flinkValidatesRunner
           arguments: |
-            -PpythonVersion=3.13 \
+            -PpythonVersion=3.14 \
       - name: Archive Python Test Results
         uses: actions/upload-artifact@v4
         if: failure()
@@ -123,4 +123,4 @@
           commit: '${{ env.prsha || env.GITHUB_SHA }}'
           comment_mode: ${{ github.event_name == 'issue_comment'  && 'always' || 'off' }}
           files: '**/pytest*.xml'
-          large_files: true
\ No newline at end of file
+          large_files: true
diff --git a/buildSrc/src/main/groovy/org/apache/beam/gradle/BeamModulePlugin.groovy b/buildSrc/src/main/groovy/org/apache/beam/gradle/BeamModulePlugin.groovy
index 434b97d..76f7198 100644
--- a/buildSrc/src/main/groovy/org/apache/beam/gradle/BeamModulePlugin.groovy
+++ b/buildSrc/src/main/groovy/org/apache/beam/gradle/BeamModulePlugin.groovy
@@ -3077,11 +3077,13 @@
       project.ext.maxPythonVersion = 14
 
       def setupVirtualenv = project.tasks.register('setupVirtualenv')  {
+        doNotTrackState("Virtualenv directory is not suitable for Gradle state tracking")
         doLast {
           def virtualenvCmd = [
             "python${project.ext.pythonVersion}",
             "-m",
             "venv",
+            "--copies",
             "--clear",
             "${project.ext.envdir}",
           ]
@@ -3096,9 +3098,9 @@
             // until it is resolved on pip's side, don't use pip's cache.
             // pip 25.1 casues :sdks:python:installGcpTest stuck. Pin to 25.0.1 for now.
             args '-c', ". ${project.ext.envdir}/bin/activate && " +
-                "pip install --pre --retries 10 --upgrade pip==25.0.1 --no-cache-dir && " +
-                "pip install --pre --retries 10 --upgrade tox --no-cache-dir && " +
-                "pip install --pre --retries 10 --upgrade setuptools build --no-cache-dir"
+                "python -m pip install --pre --retries 10 --upgrade pip==25.0.1 --no-cache-dir && " +
+                "python -m pip install --pre --retries 10 --upgrade tox --no-cache-dir && " +
+                "python -m pip install --pre --retries 10 --upgrade setuptools build --no-cache-dir"
           }
         }
         // Gradle will delete outputs whenever it thinks they are stale. Putting a
diff --git a/contributor-docs/release-guide.md b/contributor-docs/release-guide.md
index ca28fc8e..2024f10 100644
--- a/contributor-docs/release-guide.md
+++ b/contributor-docs/release-guide.md
@@ -582,7 +582,7 @@
 Verify that third party licenses are included in Docker. You can do this with a simple script:
 
     RC_TAG=${RELEASE_VERSION}rc${RC_NUM}
-    for pyver in 3.10 3.11 3.12 3.13; do
+    for pyver in 3.10 3.11 3.12 3.13 3.14; do
       docker run --rm --entrypoint sh \
           apache/beam_python${pyver}_sdk:${RC_TAG} \
           -c 'ls -al /opt/apache/beam/third_party_licenses/ | wc -l'
diff --git a/local-env-setup.sh b/local-env-setup.sh
index 209c1de..0c28b4e 100755
--- a/local-env-setup.sh
+++ b/local-env-setup.sh
@@ -55,7 +55,7 @@
         exit
     fi
 
-    for ver in 3.10 3.11 3.12 3.13 3; do
+    for ver in 3.10 3.11 3.12 3.13 3.14 3; do
         apt install --yes python$ver-venv
     done
 
@@ -89,7 +89,7 @@
         echo "Installing openjdk@8"
         brew install openjdk@8
     fi
-    for ver in 3.10 3.11 3.12 3.13; do
+    for ver in 3.10 3.11 3.12 3.13 3.14; do
       if brew ls --versions python@$ver > /dev/null; then
           echo "python@$ver already installed. Skipping"
           brew info python@$ver
diff --git a/release/src/main/python-release/python_release_automation.sh b/release/src/main/python-release/python_release_automation.sh
index 892e1c3..8f4f509 100755
--- a/release/src/main/python-release/python_release_automation.sh
+++ b/release/src/main/python-release/python_release_automation.sh
@@ -19,7 +19,7 @@
 source release/src/main/python-release/run_release_candidate_python_quickstart.sh
 source release/src/main/python-release/run_release_candidate_python_mobile_gaming.sh
 
-for version in 3.10 3.11 3.12 3.13
+for version in 3.10 3.11 3.12 3.13 3.14
 do
   run_release_candidate_python_quickstart    "tar"   "python${version}"
   run_release_candidate_python_mobile_gaming "tar"   "python${version}"