This is an automated email from the ASF dual-hosted git repository.
anandinguva pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/beam.git
The following commit(s) were added to refs/heads/master by this push:
new a94d29ffd21 Add pyproject.toml (#28385)
a94d29ffd21 is described below
commit a94d29ffd21710eac3e88be9325346171368e219
Author: Anand Inguva <[email protected]>
AuthorDate: Thu Oct 12 19:14:39 2023 +0000
Add pyproject.toml (#28385)
* Add pyproject.toml
Update numpy bounds
* Use subprocess to run grpcio since it is not imported in pyproject.toml
Update setup.py
Remove ImportError from gen_protos.py
Update subprocess run and raise RuntimeError if proto generation fails
Print output of setup.py
Fix linting issues
* Remove build-requirements.txt and use build to build the sdist
Modify buildPython task
* Use wheels to run tox precommit tests
Upgrade pip in Dockerfile
Move _ELEMENTS to shared file. tests are not importable by each other
Add missing element
Remove shared_test_variables
Remove installing wheel in a test suite
Retry run_tox.sh with no installPkg flag
Remove natural language test. codepath is covered in the postCommits.
Add back tox exit code
* Remove cython tests. default tests will run with Cython extensions
FIx toxTask name
Add no-extra test suite to precommit and remove GH duplicate ubuntu test
Skip failing non-cython test
Fix tox test name
* Force type cast inputs to list
* Update stager to use build. If it fails, use legacy setup to build sdist
Fix mypy issue
* Remove cython env and build-requirements for tox.ini
---
.github/workflows/beam_PreCommit_Python.yml | 1 +
.../workflows/beam_PreCommit_Python_Coverage.yml | 2 +
.../workflows/beam_PreCommit_Python_Dataframes.yml | 1 +
.../workflows/beam_PreCommit_Python_Examples.yml | 1 +
.../workflows/beam_PreCommit_Python_Runners.yml | 1 +
.../workflows/beam_PreCommit_Python_Transforms.yml | 1 +
.github/workflows/build_release_candidate.yml | 2 +-
.github/workflows/build_wheels.yml | 17 ++--
.github/workflows/dask_runner_tests.yml | 8 +-
.github/workflows/python_dependency_tests.yml | 5 +-
.github/workflows/python_tests.yml | 16 +---
.github/workflows/run_perf_alert_tool.yml | 3 -
.github/workflows/typescript_tests.yml | 7 +-
.test-infra/jenkins/job_PreCommit_Python.groovy | 1 +
.../jenkins/job_PreCommit_Python_Coverage.groovy | 3 +
.../jenkins/job_PreCommit_Python_Dataframes.groovy | 3 +-
.../jenkins/job_PreCommit_Python_Examples.groovy | 3 +-
.../jenkins/job_PreCommit_Python_Runners.groovy | 3 +-
.../jenkins/job_PreCommit_Python_Transforms.groovy | 3 +-
.../org/apache/beam/gradle/BeamModulePlugin.groovy | 40 +++++---
.../src/main/scripts/build_release_candidate.sh | 2 +-
sdks/python/apache_beam/coders/slow_coders_test.py | 3 +
.../apache_beam/examples/inference/README.md | 1 -
.../apache_beam/examples/kafkataxi/README.md | 4 +-
.../io/azure/integration_test/Dockerfile | 2 +-
sdks/python/apache_beam/io/gcp/bigquery_test.py | 39 +++++++-
.../io/hdfs_integration_test/Dockerfile | 2 +-
.../apache_beam/ml/gcp/naturallanguageml_test.py | 19 ----
sdks/python/apache_beam/runners/common.py | 4 +-
.../apache_beam/runners/portability/stager.py | 28 ++++--
sdks/python/build-requirements.txt | 28 ------
sdks/python/build.gradle | 7 +-
sdks/python/container/Dockerfile | 2 +-
.../container/base_image_requirements_manual.txt | 1 +
sdks/python/gen_protos.py | 105 +++++++--------------
sdks/python/pyproject.toml | 36 +++++++
sdks/python/scripts/run_pytest.sh | 4 +-
sdks/python/scripts/run_tox.sh | 19 +++-
sdks/python/setup.py | 59 +++++++-----
sdks/python/test-suites/tox/common.gradle | 12 +--
sdks/python/test-suites/tox/py310/build.gradle | 2 -
sdks/python/test-suites/tox/py311/build.gradle | 2 -
sdks/python/test-suites/tox/py38/build.gradle | 2 -
sdks/python/test-suites/tox/py39/build.gradle | 3 -
sdks/python/tox.ini | 32 +------
.../documentation/ml/multi-language-inference.md | 2 +-
.../sdks/python-pipeline-dependencies.md | 13 +--
47 files changed, 268 insertions(+), 286 deletions(-)
diff --git a/.github/workflows/beam_PreCommit_Python.yml
b/.github/workflows/beam_PreCommit_Python.yml
index c891a79cefd..35e7b937068 100644
--- a/.github/workflows/beam_PreCommit_Python.yml
+++ b/.github/workflows/beam_PreCommit_Python.yml
@@ -97,6 +97,7 @@ jobs:
arguments: |
-Pposargs="--ignore=apache_beam/dataframe/
--ignore=apache_beam/examples/ --ignore=apache_beam/runners/
--ignore=apache_beam/transforms/" \
-PpythonVersion=${{ matrix.python_version }} \
+ -PuseWheelDistribution
- name: Archive code coverage results
uses: actions/upload-artifact@v3
with:
diff --git a/.github/workflows/beam_PreCommit_Python_Coverage.yml
b/.github/workflows/beam_PreCommit_Python_Coverage.yml
index 33be9644d34..4b274d643e0 100644
--- a/.github/workflows/beam_PreCommit_Python_Coverage.yml
+++ b/.github/workflows/beam_PreCommit_Python_Coverage.yml
@@ -86,6 +86,8 @@ jobs:
uses: ./.github/actions/gradle-command-self-hosted-action
with:
gradle-command: :sdks:python:test-suites:tox:py38:preCommitPyCoverage
+ arguments: |
+ -PuseWheelDistribution
- name: Archive code coverage results
uses: actions/upload-artifact@v3
with:
diff --git a/.github/workflows/beam_PreCommit_Python_Dataframes.yml
b/.github/workflows/beam_PreCommit_Python_Dataframes.yml
index 2862d7d5936..f03716d0679 100644
--- a/.github/workflows/beam_PreCommit_Python_Dataframes.yml
+++ b/.github/workflows/beam_PreCommit_Python_Dataframes.yml
@@ -97,6 +97,7 @@ jobs:
arguments: |
-Pposargs=apache_beam/dataframe/ \
-PpythonVersion=${{ matrix.python_version }} \
+ -PuseWheelDistribution
- name: Archive code coverage results
uses: actions/upload-artifact@v3
with:
diff --git a/.github/workflows/beam_PreCommit_Python_Examples.yml
b/.github/workflows/beam_PreCommit_Python_Examples.yml
index 7f980885180..d629ee09b72 100644
--- a/.github/workflows/beam_PreCommit_Python_Examples.yml
+++ b/.github/workflows/beam_PreCommit_Python_Examples.yml
@@ -97,6 +97,7 @@ jobs:
arguments: |
-Pposargs=apache_beam/examples/ \
-PpythonVersion=${{ matrix.python_version }} \
+ -PuseWheelDistribution
- name: Archive code coverage results
uses: actions/upload-artifact@v3
with:
diff --git a/.github/workflows/beam_PreCommit_Python_Runners.yml
b/.github/workflows/beam_PreCommit_Python_Runners.yml
index b0c5ab4fa34..f823112e23d 100644
--- a/.github/workflows/beam_PreCommit_Python_Runners.yml
+++ b/.github/workflows/beam_PreCommit_Python_Runners.yml
@@ -97,6 +97,7 @@ jobs:
arguments: |
-Pposargs=apache_beam/runners/ \
-PpythonVersion=${{ matrix.python_version }} \
+ -PuseWheelDistribution
- name: Archive code coverage results
uses: actions/upload-artifact@v3
with:
diff --git a/.github/workflows/beam_PreCommit_Python_Transforms.yml
b/.github/workflows/beam_PreCommit_Python_Transforms.yml
index 88ac59c9de9..7374af7f38c 100644
--- a/.github/workflows/beam_PreCommit_Python_Transforms.yml
+++ b/.github/workflows/beam_PreCommit_Python_Transforms.yml
@@ -97,6 +97,7 @@ jobs:
arguments: |
-Pposargs=apache_beam/transforms/ \
-PpythonVersion=${{ matrix.python_version }} \
+ -PuseWheelDistribution
- name: Archive code coverage results
uses: actions/upload-artifact@v3
with:
diff --git a/.github/workflows/build_release_candidate.yml
b/.github/workflows/build_release_candidate.yml
index 3956551431c..12f1537dac1 100644
--- a/.github/workflows/build_release_candidate.yml
+++ b/.github/workflows/build_release_candidate.yml
@@ -314,7 +314,7 @@ jobs:
pip install -U pip
pip install tox
# TODO(https://github.com/apache/beam/issues/20209): Don't
hardcode py version in this file.
- pip install -r build-requirements.txt && tox -e py38-docs
+ tox -e py38-docs
rm -rf target/docs/_build/.doctrees
- name: Build Typescript Docs
working-directory: beam/sdks/typescript
diff --git a/.github/workflows/build_wheels.yml
b/.github/workflows/build_wheels.yml
index 94248be0c00..f4ccf368bac 100644
--- a/.github/workflows/build_wheels.yml
+++ b/.github/workflows/build_wheels.yml
@@ -92,11 +92,6 @@ jobs:
uses: actions/setup-python@v4
with:
python-version: 3.8
- - name: Get build dependencies
- working-directory: ./sdks/python
- run: python -m pip install -r build-requirements.txt
- - name: Install wheels
- run: python -m pip install wheel
- name: Get tag
id: get_tag
run: |
@@ -117,15 +112,15 @@ jobs:
echo "RELEASE_VERSION=$RELEASE_VERSION" >> $GITHUB_OUTPUT
- name: Build source
working-directory: ./sdks/python
- run: python setup.py sdist --formats=zip
+ run: pip install -U build && python -m build --sdist
- name: Add checksums
working-directory: ./sdks/python/dist
run: |
- file=$(ls | grep .zip | head -n 1)
+ file=$(ls | grep .tar.gz | head -n 1)
sha512sum $file > ${file}.sha512
- name: Unzip source
working-directory: ./sdks/python
- run: unzip dist/$(ls dist | grep .zip | head -n 1)
+ run: tar -xzvf dist/$(ls dist | grep .tar.gz | head -n 1)
- name: Rename source directory
working-directory: ./sdks/python
run: mv $(ls | grep apache-beam) apache-beam-source
@@ -155,17 +150,17 @@ jobs:
- name: Build RC source
if: steps.is_rc.outputs.is_rc == 1
working-directory: ./sdks/python
- run: python setup.py sdist --formats=zip
+ run: pip install -U build && pythom -m build --sdist
- name: Add RC checksums
if: steps.is_rc.outputs.is_rc == 1
working-directory: ./sdks/python/dist
run: |
- file=$(ls | grep .zip | head -n 1)
+ file=$(ls | grep .tar.gz | head -n 1)
sha512sum $file > ${file}.sha512
- name: Unzip RC source
if: steps.is_rc.outputs.is_rc == 1
working-directory: ./sdks/python
- run: unzip dist/$(ls dist | grep .zip | head -n 1)
+ run: tar -xzvf dist/$(ls dist | grep .tar.gz | head -n 1)
- name: Rename RC source directory
if: steps.is_rc.outputs.is_rc == 1
working-directory: ./sdks/python
diff --git a/.github/workflows/dask_runner_tests.yml
b/.github/workflows/dask_runner_tests.yml
index 423a304db82..35c32008699 100644
--- a/.github/workflows/dask_runner_tests.yml
+++ b/.github/workflows/dask_runner_tests.yml
@@ -44,12 +44,9 @@ jobs:
uses: actions/setup-python@v4
with:
python-version: 3.8
- - name: Get build dependencies
- working-directory: ./sdks/python
- run: pip install pip setuptools --upgrade && pip install -r
build-requirements.txt
- name: Build source
working-directory: ./sdks/python
- run: python setup.py sdist
+ run: pip install -U build && python -m build --sdist
- name: Rename source file
working-directory: ./sdks/python/dist
run: mv $(ls | grep "apache-beam.*tar\.gz") apache-beam-source.tar.gz
@@ -78,9 +75,6 @@ jobs:
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.params.py_ver }}
- - name: Get build dependencies
- working-directory: ./sdks/python
- run: pip install -r build-requirements.txt
- name: Install tox
run: pip install tox
- name: Install SDK with dask
diff --git a/.github/workflows/python_dependency_tests.yml
b/.github/workflows/python_dependency_tests.yml
index 6fd865bda75..166899df90c 100644
--- a/.github/workflows/python_dependency_tests.yml
+++ b/.github/workflows/python_dependency_tests.yml
@@ -7,7 +7,7 @@ on:
branches: ['master', 'release-*']
tags: 'v*'
# paths where Beam Python's dependencies are configured.
- paths: ['sdks/python/setup.py', 'sdks/python/build-requirements.txt',
'sdks/python/container/base_image_requirements_manual.txt']
+ paths: ['sdks/python/setup.py', 'sdks/python/pyproject.toml',
'sdks/python/container/base_image_requirements_manual.txt']
# This allows a subsequently queued workflow run to interrupt previous runs
concurrency:
@@ -38,9 +38,6 @@ jobs:
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.params.py_ver }}
- - name: Install Build dependencies
- working-directory: ./sdks/python
- run: pip install -r build-requirements.txt
- name: Install base_image_requirements.txt
working-directory: ./sdks/python
run: pip install --no-deps -r container/${{ matrix.params.py_env
}}/base_image_requirements.txt
diff --git a/.github/workflows/python_tests.yml
b/.github/workflows/python_tests.yml
index 57ec895c243..0309329e84e 100644
--- a/.github/workflows/python_tests.yml
+++ b/.github/workflows/python_tests.yml
@@ -78,12 +78,9 @@ jobs:
uses: actions/setup-python@v4
with:
python-version: 3.8
- - name: Get build dependencies
- working-directory: ./sdks/python
- run: pip install pip setuptools --upgrade && pip install -r
build-requirements.txt
- name: Build source
working-directory: ./sdks/python
- run: python setup.py sdist
+ run: pip install -U build && python -m build --sdist
- name: Rename source file
working-directory: ./sdks/python/dist
run: mv $(ls | grep "apache-beam.*tar\.gz") apache-beam-source.tar.gz
@@ -99,7 +96,7 @@ jobs:
strategy:
fail-fast: false
matrix:
- os: [ubuntu-latest, macos-latest, windows-latest]
+ os: [macos-latest, windows-latest]
params: [
{"py_ver": "3.8", "tox_env": "py38"},
{"py_ver": "3.9", "tox_env": "py39"},
@@ -113,9 +110,6 @@ jobs:
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.params.py_ver }}
- - name: Get build dependencies
- working-directory: ./sdks/python
- run: pip install -r build-requirements.txt --use-pep517
- name: Install tox
run: pip install tox
- name: Run tests basic unix
@@ -148,9 +142,6 @@ jobs:
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python }}
- - name: Get build dependencies
- working-directory: ./sdks/python
- run: pip install -r build-requirements.txt
- name: Install requirements
working-directory: ./sdks/python
run: pip install setuptools --upgrade && pip install -e .
@@ -192,9 +183,6 @@ jobs:
service_account_key: ${{ secrets.GCP_SA_KEY }}
project_id: ${{ secrets.GCP_PROJECT_ID }}
export_default_credentials: true
- - name: Get build dependencies
- working-directory: ./sdks/python
- run: pip install -r build-requirements.txt
- name: Install requirements
working-directory: ./sdks/python
run: pip install setuptools --upgrade && pip install -e ".[gcp]"
diff --git a/.github/workflows/run_perf_alert_tool.yml
b/.github/workflows/run_perf_alert_tool.yml
index 1bd8d525c2f..c61665c1bc7 100644
--- a/.github/workflows/run_perf_alert_tool.yml
+++ b/.github/workflows/run_perf_alert_tool.yml
@@ -46,9 +46,6 @@ jobs:
with:
service_account_key: ${{ secrets.GCP_SA_KEY }}
export_default_credentials: true
- - name: Get Apache Beam Build dependencies
- working-directory: ./sdks/python
- run: pip install pip setuptools --upgrade && pip install -r
build-requirements.txt
- name: Install Apache Beam
working-directory: ./sdks/python
run: pip install -e .[gcp,test]
diff --git a/.github/workflows/typescript_tests.yml
b/.github/workflows/typescript_tests.yml
index a4aa14c42ef..edbe8399e7d 100644
--- a/.github/workflows/typescript_tests.yml
+++ b/.github/workflows/typescript_tests.yml
@@ -89,10 +89,8 @@ jobs:
- name: Setup Beam Python
working-directory: ./sdks/python
run: |
- pip install pip setuptools --upgrade
- pip install -r build-requirements.txt
pip install 'pandas>=1.0,<1.5'
- python setup.py develop
+ pip install -e .
- run: npm ci
working-directory: ./sdks/typescript
- run: npm run build
@@ -146,10 +144,7 @@ jobs:
- name: Setup Beam Python
working-directory: ./sdks/python
run: |
- pip install pip setuptools --upgrade
- pip install -r build-requirements.txt
pip install 'pandas>=1.0,<1.5'
- python setup.py develop
pip install -e ".[gcp]"
- name: Authenticate on GCP
uses: google-github-actions/setup-gcloud@v0
diff --git a/.test-infra/jenkins/job_PreCommit_Python.groovy
b/.test-infra/jenkins/job_PreCommit_Python.groovy
index 0e439d78887..9c9740e3c97 100644
--- a/.test-infra/jenkins/job_PreCommit_Python.groovy
+++ b/.test-infra/jenkins/job_PreCommit_Python.groovy
@@ -29,6 +29,7 @@ PrecommitJobBuilder builder = new PrecommitJobBuilder(
'^release/.*$',
],
gradleSwitches: [
+ '-PuseWheelDistribution',
'-Pposargs=\"--ignore=apache_beam/dataframe/
--ignore=apache_beam/examples/ --ignore=apache_beam/runners/
--ignore=apache_beam/transforms/\"' // All these tests are covered by different
jobs.
],
numBuildsToRetain: 40
diff --git a/.test-infra/jenkins/job_PreCommit_Python_Coverage.groovy
b/.test-infra/jenkins/job_PreCommit_Python_Coverage.groovy
index c0cb48cf623..43a204fd7cf 100644
--- a/.test-infra/jenkins/job_PreCommit_Python_Coverage.groovy
+++ b/.test-infra/jenkins/job_PreCommit_Python_Coverage.groovy
@@ -22,6 +22,9 @@ PrecommitJobBuilder builder = new PrecommitJobBuilder(
scope: this,
nameBase: 'Python_Coverage',
gradleTask: ':sdks:python:test-suites:tox:py38:preCommitPyCoverage',
+ gradleSwitches: [
+ '-PuseWheelDistribution'
+ ],
timeoutMins: 180,
triggerPathPatterns: [
'^model/.*$',
diff --git a/.test-infra/jenkins/job_PreCommit_Python_Dataframes.groovy
b/.test-infra/jenkins/job_PreCommit_Python_Dataframes.groovy
index e2914e9bdb8..dea034f613a 100644
--- a/.test-infra/jenkins/job_PreCommit_Python_Dataframes.groovy
+++ b/.test-infra/jenkins/job_PreCommit_Python_Dataframes.groovy
@@ -23,7 +23,8 @@ PrecommitJobBuilder builder = new PrecommitJobBuilder(
nameBase: 'Python_Dataframes',
gradleTask: ':pythonPreCommit',
gradleSwitches: [
- '-Pposargs=apache_beam/dataframe/'
+ '-Pposargs=apache_beam/dataframe/',
+ '-PuseWheelDistribution'
],
timeoutMins: 180,
triggerPathPatterns: [
diff --git a/.test-infra/jenkins/job_PreCommit_Python_Examples.groovy
b/.test-infra/jenkins/job_PreCommit_Python_Examples.groovy
index f4ef9f51d7f..3dd7bf6f6f4 100644
--- a/.test-infra/jenkins/job_PreCommit_Python_Examples.groovy
+++ b/.test-infra/jenkins/job_PreCommit_Python_Examples.groovy
@@ -23,7 +23,8 @@ PrecommitJobBuilder builder = new PrecommitJobBuilder(
nameBase: 'Python_Examples',
gradleTask: ':pythonPreCommit',
gradleSwitches: [
- '-Pposargs=apache_beam/examples/'
+ '-Pposargs=apache_beam/examples/',
+ '-PuseWheelDistribution'
],
timeoutMins: 180,
triggerPathPatterns: [
diff --git a/.test-infra/jenkins/job_PreCommit_Python_Runners.groovy
b/.test-infra/jenkins/job_PreCommit_Python_Runners.groovy
index e80dba6cf5c..4ae1d283b7a 100644
--- a/.test-infra/jenkins/job_PreCommit_Python_Runners.groovy
+++ b/.test-infra/jenkins/job_PreCommit_Python_Runners.groovy
@@ -23,7 +23,8 @@ PrecommitJobBuilder builder = new PrecommitJobBuilder(
nameBase: 'Python_Runners',
gradleTask: ':pythonPreCommit',
gradleSwitches: [
- '-Pposargs=apache_beam/runners/'
+ '-Pposargs=apache_beam/runners/',
+ '-PuseWheelDistribution'
],
timeoutMins: 180,
triggerPathPatterns: [
diff --git a/.test-infra/jenkins/job_PreCommit_Python_Transforms.groovy
b/.test-infra/jenkins/job_PreCommit_Python_Transforms.groovy
index dd16d48b173..ccd3f08b78a 100644
--- a/.test-infra/jenkins/job_PreCommit_Python_Transforms.groovy
+++ b/.test-infra/jenkins/job_PreCommit_Python_Transforms.groovy
@@ -23,7 +23,8 @@ PrecommitJobBuilder builder = new PrecommitJobBuilder(
nameBase: 'Python_Transforms',
gradleTask: ':pythonPreCommit',
gradleSwitches: [
- '-Pposargs=apache_beam/transforms/'
+ '-Pposargs=apache_beam/transforms/',
+ '-PuseWheelDistribution'
],
timeoutMins: 180,
triggerPathPatterns: [
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 c32717aae72..6fa5ff0ee5f 100644
--- a/buildSrc/src/main/groovy/org/apache/beam/gradle/BeamModulePlugin.groovy
+++ b/buildSrc/src/main/groovy/org/apache/beam/gradle/BeamModulePlugin.groovy
@@ -2998,7 +2998,7 @@ class BeamModulePlugin implements Plugin<Project> {
executable 'sh'
args '-c', ". ${project.ext.envdir}/bin/activate && " +
"pip install --pre --retries 10 --upgrade pip && " +
- "pip install --pre --retries 10 --upgrade tox -r
${project.rootDir}/sdks/python/build-requirements.txt"
+ "pip install --pre --retries 10 --upgrade tox"
}
}
// Gradle will delete outputs whenever it thinks they are stale.
Putting a
@@ -3081,30 +3081,40 @@ class BeamModulePlugin implements Plugin<Project> {
}
return argList.join(' ')
}
-
project.ext.toxTask = { name, tox_env, posargs='' ->
project.tasks.register(name) {
dependsOn setupVirtualenv
dependsOn ':sdks:python:sdist'
-
- doLast {
- // Python source directory is also tox execution workspace, We want
- // to isolate them per tox suite to avoid conflict when running
- // multiple tox suites in parallel.
- project.copy { from project.pythonSdkDeps; into copiedSrcRoot }
-
- def copiedPyRoot = "${copiedSrcRoot}/sdks/python"
- def distTarBall = "${pythonRootDir}/build/apache-beam.tar.gz"
- project.exec {
- executable 'sh'
- args '-c', ". ${project.ext.envdir}/bin/activate && cd
${copiedPyRoot} && scripts/run_tox.sh $tox_env $distTarBall '$posargs'"
+ if (project.hasProperty('useWheelDistribution')) {
+ def pythonVersionNumber = project.ext.pythonVersion.replace('.',
'')
+ dependsOn ":sdks:python:bdistPy${pythonVersionNumber}linux"
+ doLast {
+ project.copy { from project.pythonSdkDeps; into copiedSrcRoot }
+ def copiedPyRoot = "${copiedSrcRoot}/sdks/python"
+ def collection =
project.fileTree(project.project(':sdks:python').buildDir){
+ include
"**/apache_beam-*cp${pythonVersionNumber}*manylinux*.whl"
+ }
+ String packageFilename = collection.singleFile.toString()
+ project.exec {
+ executable 'sh'
+ args '-c', ". ${project.ext.envdir}/bin/activate && cd
${copiedPyRoot} && scripts/run_tox.sh $tox_env ${packageFilename} '$posargs' "
+ }
+ }
+ } else {
+ // tox task will run in editable mode, which is configured in the
tox.ini file.
+ doLast {
+ project.copy { from project.pythonSdkDeps; into copiedSrcRoot }
+ def copiedPyRoot = "${copiedSrcRoot}/sdks/python"
+ project.exec {
+ executable 'sh'
+ args '-c', ". ${project.ext.envdir}/bin/activate && cd
${copiedPyRoot} && scripts/run_tox.sh $tox_env '$posargs'"
+ }
}
}
inputs.files project.pythonSdkDeps
outputs.files project.fileTree(dir:
"${pythonRootDir}/target/.tox/${tox_env}/log/")
}
}
-
// Run single or a set of integration tests with provided test options
and pipeline options.
project.ext.enablePythonPerformanceTest = {
diff --git a/release/src/main/scripts/build_release_candidate.sh
b/release/src/main/scripts/build_release_candidate.sh
index 057a38833ad..d0e6310f50a 100755
--- a/release/src/main/scripts/build_release_candidate.sh
+++ b/release/src/main/scripts/build_release_candidate.sh
@@ -346,7 +346,7 @@ if [[ $confirmation = "y" ]]; then
cd ${BEAM_ROOT_DIR}
RELEASE_COMMIT=$(git rev-list -n 1 "tags/${RC_TAG}")
# TODO(https://github.com/apache/beam/issues/20209): Don't hardcode py
version in this file.
- cd sdks/python && pip install -r build-requirements.txt && tox -e py38-docs
+ cd sdks/python && tox -e py38-docs
GENERATED_PYDOC=~/${LOCAL_WEBSITE_UPDATE_DIR}/${LOCAL_PYTHON_DOC}/${BEAM_ROOT_DIR}/sdks/python/target/docs/_build
rm -rf ${GENERATED_PYDOC}/.doctrees
diff --git a/sdks/python/apache_beam/coders/slow_coders_test.py
b/sdks/python/apache_beam/coders/slow_coders_test.py
index fe1c707a62e..7915116a19a 100644
--- a/sdks/python/apache_beam/coders/slow_coders_test.py
+++ b/sdks/python/apache_beam/coders/slow_coders_test.py
@@ -25,6 +25,9 @@ import unittest
from apache_beam.coders.coders_test_common import *
[email protected](
+ 'Remove non-cython tests.'
+ 'https://github.com/apache/beam/issues/28307')
class SlowCoders(unittest.TestCase):
def test_using_slow_impl(self):
try:
diff --git a/sdks/python/apache_beam/examples/inference/README.md
b/sdks/python/apache_beam/examples/inference/README.md
index 19262dead58..cd92d9c127e 100644
--- a/sdks/python/apache_beam/examples/inference/README.md
+++ b/sdks/python/apache_beam/examples/inference/README.md
@@ -29,7 +29,6 @@ Some examples are also used in [our
benchmarks](http://s.apache.org/beam-communi
You must have the latest (possibly unreleased) `apache-beam` or greater
installed from the Beam repo in order to run these pipelines,
because some examples rely on the latest features that are actively in
development. To install Beam, run the following from the `sdks/python`
directory:
```
-pip install -r build-requirements.txt
pip install -e .[gcp]
```
diff --git a/sdks/python/apache_beam/examples/kafkataxi/README.md
b/sdks/python/apache_beam/examples/kafkataxi/README.md
index c4e808cad8b..72a8d8f85c0 100644
--- a/sdks/python/apache_beam/examples/kafkataxi/README.md
+++ b/sdks/python/apache_beam/examples/kafkataxi/README.md
@@ -157,9 +157,9 @@ Install Beam and dependencies and build a Beam distribution.
```sh
cd beam/sdks/python
-pip install -r build-requirements.txt
pip install -e '.[gcp]'
-python setup.py sdist
+pip install -q build
+python -m build --sdist
```
Run the Beam pipeline. You can either use the default Kafka topic name or
specify
diff --git a/sdks/python/apache_beam/io/azure/integration_test/Dockerfile
b/sdks/python/apache_beam/io/azure/integration_test/Dockerfile
index e9ac396b8e1..257fa72cb66 100644
--- a/sdks/python/apache_beam/io/azure/integration_test/Dockerfile
+++ b/sdks/python/apache_beam/io/azure/integration_test/Dockerfile
@@ -32,7 +32,7 @@ COPY sdks/python /app/sdks/python
COPY model /app/model
# This step should look like setupVirtualenv minus virtualenv creation.
-RUN pip install --no-cache-dir tox -r sdks/python/build-requirements.txt
+RUN pip install --no-cache-dir tox
# Add Azurite's self-signed cert to the global CA cert store.
COPY cert.pem /usr/local/share/ca-certificates/azurite.crt
diff --git a/sdks/python/apache_beam/io/gcp/bigquery_test.py
b/sdks/python/apache_beam/io/gcp/bigquery_test.py
index 7e9c1e63474..95b6c2a5fa6 100644
--- a/sdks/python/apache_beam/io/gcp/bigquery_test.py
+++ b/sdks/python/apache_beam/io/gcp/bigquery_test.py
@@ -49,14 +49,12 @@ from apache_beam.io.gcp.bigquery import ReadFromBigQuery
from apache_beam.io.gcp.bigquery import TableRowJsonCoder
from apache_beam.io.gcp.bigquery import WriteToBigQuery
from apache_beam.io.gcp.bigquery import _StreamToBigQuery
-from apache_beam.io.gcp.bigquery_file_loads_test import _ELEMENTS
from apache_beam.io.gcp.bigquery_read_internal import _JsonToDictCoder
from apache_beam.io.gcp.bigquery_read_internal import
bigquery_export_destination_uri
from apache_beam.io.gcp.bigquery_tools import JSON_COMPLIANCE_ERROR
from apache_beam.io.gcp.bigquery_tools import BigQueryWrapper
from apache_beam.io.gcp.bigquery_tools import RetryStrategy
from apache_beam.io.gcp.internal.clients import bigquery
-from apache_beam.io.gcp.internal.clients.bigquery import bigquery_v2_client
from apache_beam.io.gcp.pubsub import ReadFromPubSub
from apache_beam.io.gcp.tests import utils
from apache_beam.io.gcp.tests.bigquery_matcher import BigqueryFullResultMatcher
@@ -82,6 +80,7 @@ from apache_beam.transforms.display_test import
DisplayDataItemMatcher
# pylint: disable=wrong-import-order, wrong-import-position
try:
+ from apache_beam.io.gcp.internal.clients.bigquery import bigquery_v2_client
from apitools.base.py.exceptions import HttpError
from google.cloud import bigquery as gcp_bigquery
from google.api_core import exceptions
@@ -93,6 +92,42 @@ except ImportError:
_LOGGER = logging.getLogger(__name__)
+_ELEMENTS = [
+ {
+ 'name': 'beam', 'language': 'py'
+ },
+ {
+ 'name': 'beam', 'language': 'java'
+ },
+ {
+ 'name': 'beam', 'language': 'go'
+ },
+ {
+ 'name': 'flink', 'language': 'java'
+ },
+ {
+ 'name': 'flink', 'language': 'scala'
+ },
+ {
+ 'name': 'spark', 'language': 'scala'
+ },
+ {
+ 'name': 'spark', 'language': 'py'
+ },
+ {
+ 'name': 'spark', 'language': 'scala'
+ },
+ {
+ 'name': 'beam', 'foundation': 'apache'
+ },
+ {
+ 'name': 'flink', 'foundation': 'apache'
+ },
+ {
+ 'name': 'spark', 'foundation': 'apache'
+ },
+]
+
def _load_or_default(filename):
try:
diff --git a/sdks/python/apache_beam/io/hdfs_integration_test/Dockerfile
b/sdks/python/apache_beam/io/hdfs_integration_test/Dockerfile
index 487d5c3487a..ab794056339 100644
--- a/sdks/python/apache_beam/io/hdfs_integration_test/Dockerfile
+++ b/sdks/python/apache_beam/io/hdfs_integration_test/Dockerfile
@@ -30,7 +30,7 @@ COPY sdks/python /app/sdks/python
COPY model /app/model
# This step should look like setupVirtualenv minus virtualenv creation.
-RUN pip install --no-cache-dir tox -r sdks/python/build-requirements.txt
+RUN pip install --no-cache-dir tox
# Run wordcount, and write results to HDFS.
CMD cd sdks/python && tox -e hdfs_integration_test
diff --git a/sdks/python/apache_beam/ml/gcp/naturallanguageml_test.py
b/sdks/python/apache_beam/ml/gcp/naturallanguageml_test.py
index bad7443d0d9..891726cb268 100644
--- a/sdks/python/apache_beam/ml/gcp/naturallanguageml_test.py
+++ b/sdks/python/apache_beam/ml/gcp/naturallanguageml_test.py
@@ -20,11 +20,7 @@
import unittest
-import mock
-
-import apache_beam as beam
from apache_beam.metrics import MetricsFilter
-from apache_beam.testing.test_pipeline import TestPipeline
# Protect against environments where Google Cloud Natural Language client
# is not available.
@@ -60,21 +56,6 @@ class NaturalLanguageMlTest(unittest.TestCase):
self.assertFalse('content' in dict_)
self.assertTrue('gcs_content_uri' in dict_)
- def test_annotate_test_called(self):
- with mock.patch('apache_beam.ml.gcp.naturallanguageml._AnnotateTextFn'
- '._get_api_client'):
- p = TestPipeline()
- features = [
- naturallanguageml.language_v1.AnnotateTextRequest.Features(
- extract_syntax=True)
- ]
- _ = (
- p | beam.Create([naturallanguageml.Document('Hello, world!')])
- | naturallanguageml.AnnotateText(features))
- result = p.run()
- result.wait_until_finish()
- self.assertCounterEqual(result, 'api_calls', 1)
-
if __name__ == '__main__':
unittest.main()
diff --git a/sdks/python/apache_beam/runners/common.py
b/sdks/python/apache_beam/runners/common.py
index 99cd26cc409..ed0dc2d9a0c 100644
--- a/sdks/python/apache_beam/runners/common.py
+++ b/sdks/python/apache_beam/runners/common.py
@@ -765,6 +765,7 @@ class PerWindowInvoker(DoFnInvoker):
# Try to prepare all the arguments that can just be filled in
# without any additional work. in the process function.
# Also cache all the placeholders needed in the process function.
+ input_args = list(input_args)
(
self.placeholders_for_process,
self.args_for_process,
@@ -1437,7 +1438,8 @@ class DoFnRunner:
return []
def _maybe_sample_exception(
- self, exn: BaseException, windowed_value: WindowedValue) -> None:
+ self, exn: BaseException,
+ windowed_value: Optional[WindowedValue]) -> None:
if self.execution_context is None:
return
diff --git a/sdks/python/apache_beam/runners/portability/stager.py
b/sdks/python/apache_beam/runners/portability/stager.py
index ace573de0a6..4afe5eaaa37 100644
--- a/sdks/python/apache_beam/runners/portability/stager.py
+++ b/sdks/python/apache_beam/runners/portability/stager.py
@@ -49,6 +49,7 @@ TODO(silviuc): We should allow customizing the exact command
for setup build.
import glob
import hashlib
+import importlib.util
import logging
import os
import shutil
@@ -771,13 +772,26 @@ class Stager(object):
try:
os.chdir(os.path.dirname(setup_file))
if build_setup_args is None:
- build_setup_args = [
- Stager._get_python_executable(),
- os.path.basename(setup_file),
- 'sdist',
- '--dist-dir',
- temp_dir
- ]
+ # if build is installed in the user env, use it to
+ # build the sdist else fallback to legacy setup.py sdist call.
+ if importlib.util.find_spec('build'):
+ build_setup_args = [
+ Stager._get_python_executable(),
+ '-m',
+ 'build',
+ '--sdist',
+ '--outdir',
+ temp_dir,
+ os.path.dirname(setup_file),
+ ]
+ else:
+ build_setup_args = [
+ Stager._get_python_executable(),
+ os.path.basename(setup_file),
+ 'sdist',
+ '--dist-dir',
+ temp_dir
+ ]
_LOGGER.info('Executing command: %s', build_setup_args)
processes.check_output(build_setup_args)
output_files = glob.glob(os.path.join(temp_dir, '*.tar.gz'))
diff --git a/sdks/python/build-requirements.txt
b/sdks/python/build-requirements.txt
deleted file mode 100644
index 4fe47079d8d..00000000000
--- a/sdks/python/build-requirements.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# TODO(https://github.com/apache/beam/issues/20051): Consider PEP-517/PEP-518
instead of this file.
-
-setuptools
-wheel>=0.36.0
-grpcio-tools==1.53.0
-mypy-protobuf==3.5.0
-# Avoid https://github.com/pypa/virtualenv/issues/2006
-distlib==0.3.7
-
-# Numpy headers
-numpy>=1.14.3,<1.26
diff --git a/sdks/python/build.gradle b/sdks/python/build.gradle
index 762bed268d6..7795e77e396 100644
--- a/sdks/python/build.gradle
+++ b/sdks/python/build.gradle
@@ -30,7 +30,8 @@ def buildPython = tasks.register("buildPython") {
logger.info('Building Python Dependencies')
exec {
executable 'sh'
- args '-c', ". ${envdir}/bin/activate && python setup.py build
--build-base ${buildDir}"
+ // args '-c', ". ${envdir}/bin/activate && python setup.py build
--build-base ${buildDir}"
+ args '-c', ". ${envdir}/bin/activate && pip install -e ."
}
}
}
@@ -46,7 +47,7 @@ def sdist = tasks.register("sdist") {
// Build artifact
exec {
executable 'sh'
- args '-c', ". ${envdir}/bin/activate && python setup.py -q sdist
--formats zip,gztar --dist-dir ${buildDir}"
+ args '-c', ". ${envdir}/bin/activate && pip install -U build && python
-m build --sdist --outdir=${buildDir}"
}
def collection = fileTree(buildDir){ include
"**/*${project.sdk_version}*.tar.gz" exclude 'srcs/**'}
@@ -96,7 +97,6 @@ platform_identifiers_map.each { platform, idsuffix ->
exec {
environment CIBW_BUILD: "cp${pyversion}-${idsuffix}"
environment CIBW_ENVIRONMENT: "SETUPTOOLS_USE_DISTUTILS=stdlib"
- environment CIBW_BEFORE_BUILD: "pip install cython==0.29.36 numpy
--config-settings=setup-args='-Dallow-noblas=true' && pip install --upgrade
setuptools"
// note: sync cibuildwheel version with GitHub Action
// .github/workflow/build_wheel.yml:build_wheels "Install
cibuildwheel" step
executable 'sh'
@@ -110,6 +110,7 @@ platform_identifiers_map.each { platform, idsuffix ->
}
}
+
/*************************************************************************************************/
// Non-testing builds and analysis tasks
diff --git a/sdks/python/container/Dockerfile b/sdks/python/container/Dockerfile
index 73d83343e03..a49933ee660 100644
--- a/sdks/python/container/Dockerfile
+++ b/sdks/python/container/Dockerfile
@@ -45,7 +45,7 @@ RUN \
&& \
rm -rf /var/lib/apt/lists/* && \
- pip install --upgrade setuptools && \
+ pip install --upgrade pip setuptools wheel && \
# Install required packages for Beam Python SDK and common dependencies
used by users.
# use --no-deps to ensure the list includes all transitive dependencies.
diff --git a/sdks/python/container/base_image_requirements_manual.txt
b/sdks/python/container/base_image_requirements_manual.txt
index e952b212660..f2f3ea44b44 100644
--- a/sdks/python/container/base_image_requirements_manual.txt
+++ b/sdks/python/container/base_image_requirements_manual.txt
@@ -43,3 +43,4 @@ nose==1.3.7 # For Dataflow internal testing. TODO: remove
this.
python-snappy;python_version<"3.11" # Optimizes execution of some Beam
codepaths.
scipy
scikit-learn
+build>=1.0,<2 # tool to build sdist from setup.py in stager.
\ No newline at end of file
diff --git a/sdks/python/gen_protos.py b/sdks/python/gen_protos.py
index 94d80c8d263..2b488af0afb 100644
--- a/sdks/python/gen_protos.py
+++ b/sdks/python/gen_protos.py
@@ -18,7 +18,7 @@
"""
Generates Python proto modules and grpc stubs for Beam protos.
"""
-
+import argparse
import contextlib
import glob
import inspect
@@ -27,9 +27,7 @@ import os
import platform
import re
import shutil
-import subprocess
import sys
-import time
from collections import defaultdict
from importlib import import_module
@@ -60,7 +58,7 @@ LICENSE_HEADER = """
NO_PROMISES_NOTICE = """
\"\"\"
For internal use only; no backwards-compatibility guarantees.
-Automatically generated when running setup.py sdist or build[_py].
+Automatically generated when running python -m build.
\"\"\"
"""
@@ -321,43 +319,6 @@ def find_by_ext(root_dir, ext):
if file.endswith(ext):
yield clean_path(os.path.join(root, file))
-
-def ensure_grpcio_exists():
- try:
- from grpc_tools import protoc # pylint: disable=unused-import
- except ImportError:
- return _install_grpcio_tools()
-
-
-def _install_grpcio_tools():
- """
- Though wheels are available for grpcio-tools, setup_requires uses
- easy_install which doesn't understand them. This means that it is
- compiled from scratch (which is expensive as it compiles the full
- protoc compiler). Instead, we attempt to install a wheel in a temporary
- directory and add it to the path as needed.
- See https://github.com/pypa/setuptools/issues/377
- """
- install_path = os.path.join(PYTHON_SDK_ROOT, '.eggs', 'grpcio-wheels')
- logging.warning('Installing grpcio-tools into %s', install_path)
- start = time.time()
- subprocess.check_call([
- sys.executable,
- '-m',
- 'pip',
- 'install',
- '--target',
- install_path,
- '--upgrade',
- '-r',
- os.path.join(PYTHON_SDK_ROOT, 'build-requirements.txt')
- ])
- logging.warning(
- 'Installing grpcio-tools took %0.2f seconds.', time.time() - start)
-
- return install_path
-
-
def build_relative_import(root_path, import_path, start_file_path):
tail_path = import_path.replace('.', os.path.sep)
source_path = os.path.join(root_path, tail_path)
@@ -511,33 +472,31 @@ def generate_proto_files(force=False):
if not os.path.exists(PYTHON_OUTPUT_PATH):
os.mkdir(PYTHON_OUTPUT_PATH)
- grpcio_install_loc = ensure_grpcio_exists()
protoc_gen_mypy = _find_protoc_gen_mypy()
- with PythonPath(grpcio_install_loc):
- from grpc_tools import protoc
- builtin_protos = pkg_resources.resource_filename('grpc_tools', '_proto')
- args = (
- [sys.executable] + # expecting to be called from command line
- ['--proto_path=%s' % builtin_protos] +
- ['--proto_path=%s' % d
- for d in proto_dirs] + ['--python_out=%s' % PYTHON_OUTPUT_PATH] +
- ['--plugin=protoc-gen-mypy=%s' % protoc_gen_mypy] +
- # new version of mypy-protobuf converts None to zero default value
- # and remove Optional from the param type annotation. This causes
- # some mypy errors. So to mitigate and fall back to old behavior,
- # use `relax_strict_optional_primitives` flag. more at
- #
https://github.com/nipunn1313/mypy-protobuf/tree/main#relax_strict_optional_primitives
# pylint:disable=line-too-long
- ['--mypy_out=relax_strict_optional_primitives:%s' % PYTHON_OUTPUT_PATH
- ] +
- # TODO(robertwb): Remove the prefix once it's the default.
- ['--grpc_python_out=grpc_2_0:%s' % PYTHON_OUTPUT_PATH] + proto_files)
-
- LOG.info('Regenerating Python proto definitions (%s).' % regenerate_reason)
- ret_code = protoc.main(args)
- if ret_code:
- raise RuntimeError(
- 'Protoc returned non-zero status (see logs for details): '
- '%s' % ret_code)
+ from grpc_tools import protoc
+ builtin_protos = pkg_resources.resource_filename('grpc_tools', '_proto')
+ args = (
+ [sys.executable] + # expecting to be called from command line
+ ['--proto_path=%s' % builtin_protos] +
+ ['--proto_path=%s' % d
+ for d in proto_dirs] + ['--python_out=%s' % PYTHON_OUTPUT_PATH] +
+ ['--plugin=protoc-gen-mypy=%s' % protoc_gen_mypy] +
+ # new version of mypy-protobuf converts None to zero default value
+ # and remove Optional from the param type annotation. This causes
+ # some mypy errors. So to mitigate and fall back to old behavior,
+ # use `relax_strict_optional_primitives` flag. more at
+ #
https://github.com/nipunn1313/mypy-protobuf/tree/main#relax_strict_optional_primitives
# pylint:disable=line-too-long
+ ['--mypy_out=relax_strict_optional_primitives:%s' % PYTHON_OUTPUT_PATH
+ ] +
+ # TODO(robertwb): Remove the prefix once it's the default.
+ ['--grpc_python_out=grpc_2_0:%s' % PYTHON_OUTPUT_PATH] + proto_files)
+
+ LOG.info('Regenerating Python proto definitions (%s).' % regenerate_reason)
+ ret_code = protoc.main(args)
+ if ret_code:
+ raise RuntimeError(
+ 'Protoc returned non-zero status (see logs for details): '
+ '%s' % ret_code)
# copy resource files
for path in MODEL_RESOURCES:
@@ -548,7 +507,7 @@ def generate_proto_files(force=False):
# force relative import paths for proto files
compiled_import_re = re.compile('^from (.*) import (.*)$')
for file_path in find_by_ext(PYTHON_OUTPUT_PATH,
- ('_pb2.py', '_pb2_grpc.py', '_pb2.pyi')):
+ ('_pb2.py', '_pb2_grpc.py', '_pb2.pyi')):
proto_packages.add(os.path.dirname(file_path))
lines = []
with open(file_path, encoding='utf-8') as f:
@@ -566,12 +525,14 @@ def generate_proto_files(force=False):
f.writelines(lines)
generate_init_files_lite(PYTHON_OUTPUT_PATH)
- with PythonPath(grpcio_install_loc):
- for proto_package in proto_packages:
- generate_urn_files(proto_package, PYTHON_OUTPUT_PATH)
+ for proto_package in proto_packages:
+ generate_urn_files(proto_package, PYTHON_OUTPUT_PATH)
generate_init_files_full(PYTHON_OUTPUT_PATH)
if __name__ == '__main__':
- generate_proto_files(force=True)
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--no-force', dest='force', action='store_false')
+ args = parser.parse_args()
+ generate_proto_files(force=args.force)
diff --git a/sdks/python/pyproject.toml b/sdks/python/pyproject.toml
new file mode 100644
index 00000000000..d185c45f619
--- /dev/null
+++ b/sdks/python/pyproject.toml
@@ -0,0 +1,36 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# since we rely on setuptools and according to
https://peps.python.org/pep-0518/#build-system-table
+# this is the minimum requirements for the build system to execute.
+[build-system]
+requires = [
+ "setuptools",
+ "wheel>=0.36.0",
+ "grpcio-tools==1.53.0",
+ "mypy-protobuf==3.5.0",
+ # Avoid https://github.com/pypa/virtualenv/issues/2006
+ "distlib==0.3.7",
+ # Numpy headers
+ "numpy>=1.14.3,<1.25", # Update setup.py as well.
+ # having cython here will create wheels that are platform dependent.
+ "cython==0.29.36",
+]
+
+
+# legacy installation is needed to generate `apache_beam.portability.api`
package.
+build-backend = "setuptools.build_meta"
\ No newline at end of file
diff --git a/sdks/python/scripts/run_pytest.sh
b/sdks/python/scripts/run_pytest.sh
index 01f2318164c..ad35b48972b 100755
--- a/sdks/python/scripts/run_pytest.sh
+++ b/sdks/python/scripts/run_pytest.sh
@@ -42,10 +42,10 @@ echo "posargs: $posargs"
# Run with pytest-xdist and without.
pytest -o junit_suite_name=${envname} \
- --junitxml=pytest_${envname}.xml -m 'not no_xdist' -n 6 ${pytest_args}
--pyargs ${posargs}
+ --junitxml=pytest_${envname}.xml -m 'not no_xdist' -n 6
--import-mode=importlib ${pytest_args} --pyargs ${posargs}
status1=$?
pytest -o junit_suite_name=${envname}_no_xdist \
- --junitxml=pytest_${envname}_no_xdist.xml -m 'no_xdist' ${pytest_args}
--pyargs ${posargs}
+ --junitxml=pytest_${envname}_no_xdist.xml -m 'no_xdist'
--import-mode=importlib ${pytest_args} --pyargs ${posargs}
status2=$?
# Exit with error if no tests were run in either suite (status code 5).
diff --git a/sdks/python/scripts/run_tox.sh b/sdks/python/scripts/run_tox.sh
index ebbacf5494e..ac60f26b32b 100755
--- a/sdks/python/scripts/run_tox.sh
+++ b/sdks/python/scripts/run_tox.sh
@@ -53,12 +53,21 @@ if [[ "$JENKINS_HOME" != "" ]]; then
export PY_COLORS=1
fi
-if [[ ! -z $2 ]]; then
+# Determine if the second argument is SDK_LOCATION or posargs
+if [[ -f "$1" ]]; then # Check if the argument corresponds to a file
SDK_LOCATION="$1"
- shift;
- tox -c tox.ini run --recreate -e "$TOX_ENVIRONMENT" --installpkg
"$SDK_LOCATION" -- "$@"
-else
- tox -c tox.ini run --recreate -e "$TOX_ENVIRONMENT"
+ shift
+fi
+
+# If SDK_LOCATION is identified and there are still arguments left, those are
posargs.
+if [[ ! -z "$SDK_LOCATION" ]]; then
+ if [[ $# -gt 0 ]]; then # There are posargs
+ tox -c tox.ini run --recreate -e "$TOX_ENVIRONMENT" --installpkg
"$SDK_LOCATION" -- "$@"
+ else
+ tox -c tox.ini run --recreate -e "$TOX_ENVIRONMENT" --installpkg
"$SDK_LOCATION"
+ fi
+else # No SDK_LOCATION; all arguments are posargs
+ tox -c tox.ini run --recreate -e "$TOX_ENVIRONMENT" -- "$@"
fi
exit_code=$?
diff --git a/sdks/python/setup.py b/sdks/python/setup.py
index ca585ccf716..4a05544526f 100644
--- a/sdks/python/setup.py
+++ b/sdks/python/setup.py
@@ -18,6 +18,7 @@
"""Apache Beam SDK for Python setup file."""
import os
+import subprocess
import sys
import warnings
# Pylint and isort disagree here.
@@ -62,7 +63,6 @@ class mypy(Command):
return os.path.join(project_path, to_filename(ei_cmd.egg_name))
def run(self):
- import subprocess
args = ['mypy', self.get_project_path()]
result = subprocess.call(args)
if result != 0:
@@ -155,12 +155,18 @@ dataframe_dependency = [
# We must generate protos after setup_requires are installed.
def generate_protos_first():
try:
- # pylint: disable=wrong-import-position
- import gen_protos
- gen_protos.generate_proto_files()
-
- except ImportError:
- warnings.warn("Could not import gen_protos, skipping proto generation.")
+ # Pyproject toml build happens in isolated environemnts. In those envs,
+ # gen_protos is unable to get imported. so we run a subprocess call.
+ cwd = os.path.abspath(os.path.dirname(__file__))
+ out = subprocess.run([
+ sys.executable,
+ os.path.join(cwd, 'gen_protos.py'),
+ '--no-force'
+ ], capture_output=True, check=True)
+ print(out.stdout)
+ except subprocess.CalledProcessError as err:
+ raise RuntimeError('Could not generate protos due to error: %s',
+ err.stderr)
def get_portability_package_data():
@@ -188,6 +194,27 @@ if __name__ == '__main__':
# structure must exist before the call to setuptools.find_packages()
# executes below.
generate_protos_first()
+
+ # generate cythonize extensions only if we are building a wheel or
+ # building an extension or running in editable mode.
+ cythonize_cmds = ('bdist_wheel', 'build_ext', 'editable_wheel')
+ if any(cmd in sys.argv for cmd in cythonize_cmds):
+ extensions = cythonize([
+ 'apache_beam/**/*.pyx',
+ 'apache_beam/coders/coder_impl.py',
+ 'apache_beam/metrics/cells.py',
+ 'apache_beam/metrics/execution.py',
+ 'apache_beam/runners/common.py',
+ 'apache_beam/runners/worker/logger.py',
+ 'apache_beam/runners/worker/opcounters.py',
+ 'apache_beam/runners/worker/operations.py',
+ 'apache_beam/transforms/cy_combiners.py',
+ 'apache_beam/transforms/stats.py',
+ 'apache_beam/utils/counters.py',
+ 'apache_beam/utils/windowed_value.py',
+ ])
+ else:
+ extensions = []
# Keep all dependencies inlined in the setup call, otherwise Dependabot won't
# be able to parse it.
setuptools.setup(
@@ -213,21 +240,7 @@ if __name__ == '__main__':
*get_portability_package_data()
]
},
- ext_modules=cythonize([
- 'apache_beam/**/*.pyx',
- 'apache_beam/coders/coder_impl.py',
- 'apache_beam/metrics/cells.py',
- 'apache_beam/metrics/execution.py',
- 'apache_beam/runners/common.py',
- 'apache_beam/runners/worker/logger.py',
- 'apache_beam/runners/worker/opcounters.py',
- 'apache_beam/runners/worker/operations.py',
- 'apache_beam/transforms/cy_combiners.py',
- 'apache_beam/transforms/stats.py',
- 'apache_beam/utils/counters.py',
- 'apache_beam/utils/windowed_value.py',
- ],
- language_level=3),
+ ext_modules=extensions,
install_requires=[
'crcmod>=1.7,<2.0',
'orjson>=3.9.7,<4',
@@ -250,7 +263,7 @@ if __name__ == '__main__':
'js2py>=0.74,<1',
# numpy can have breaking changes in minor versions.
# Use a strict upper bound.
- 'numpy>=1.14.3,<1.25.0', # Update build-requirements.txt as well.
+ 'numpy>=1.14.3,<1.25.0', # Update pyproject.toml as well.
'objsize>=0.6.1,<0.7.0',
'packaging>=22.0',
'pymongo>=3.8.0,<5.0.0',
diff --git a/sdks/python/test-suites/tox/common.gradle
b/sdks/python/test-suites/tox/common.gradle
index ee183dff406..3fdd0c0c553 100644
--- a/sdks/python/test-suites/tox/common.gradle
+++ b/sdks/python/test-suites/tox/common.gradle
@@ -29,18 +29,12 @@ test.dependsOn "testPy${pythonVersionSuffix}Cloud"
// toxTask "testPy${pythonVersionSuffix}Dask",
"py${pythonVersionSuffix}-dask", "${posargs}"
// test.dependsOn "testPy${pythonVersionSuffix}Dask"
-toxTask "testPy${pythonVersionSuffix}Cython",
"py${pythonVersionSuffix}-cython", "${posargs}"
-test.dependsOn "testPy${pythonVersionSuffix}Cython"
toxTask "testPy38CloudCoverage", "py38-cloudcoverage", "${posargs}"
test.dependsOn "testPy38CloudCoverage"
project.tasks.register("preCommitPy${pythonVersionSuffix}") {
- // Since codecoverage reports will always be generated for py38,
- // all tests will be exercised.
- if (pythonVersionSuffix.equals('38')) {
- dependsOn = ["testPy38Cython"]
- } else {
- dependsOn = ["testPy${pythonVersionSuffix}Cloud",
"testPy${pythonVersionSuffix}Cython"]
- }
+ // Since codecoverage reports will always be generated for py38,
+ // all tests will be exercised.
+ dependsOn = ["testPy${pythonVersionSuffix}Cloud",
"testPython${pythonVersionSuffix}"]
}
\ No newline at end of file
diff --git a/sdks/python/test-suites/tox/py310/build.gradle
b/sdks/python/test-suites/tox/py310/build.gradle
index ea10fde831c..f1e40a17951 100644
--- a/sdks/python/test-suites/tox/py310/build.gradle
+++ b/sdks/python/test-suites/tox/py310/build.gradle
@@ -28,5 +28,3 @@ pythonVersion = '3.10'
apply from: "../common.gradle"
-// TODO(https://github.com/apache/beam/issues/20051): Remove this once tox
uses isolated builds.
-testPy310Cython.mustRunAfter testPython310, testPy310Cloud
diff --git a/sdks/python/test-suites/tox/py311/build.gradle
b/sdks/python/test-suites/tox/py311/build.gradle
index 1bb3766500b..fabf9fd4365 100644
--- a/sdks/python/test-suites/tox/py311/build.gradle
+++ b/sdks/python/test-suites/tox/py311/build.gradle
@@ -28,5 +28,3 @@ pythonVersion = '3.11'
apply from: "../common.gradle"
-// TODO(https://github.com/apache/beam/issues/20051): Remove this once tox
uses isolated builds.
-testPy311Cython.mustRunAfter testPython311, testPy311Cloud
diff --git a/sdks/python/test-suites/tox/py38/build.gradle
b/sdks/python/test-suites/tox/py38/build.gradle
index bc4aa99c79b..b1ed5f88c7c 100644
--- a/sdks/python/test-suites/tox/py38/build.gradle
+++ b/sdks/python/test-suites/tox/py38/build.gradle
@@ -43,8 +43,6 @@ lint.dependsOn mypyPy38
apply from: "../common.gradle"
-// TODO(https://github.com/apache/beam/issues/20051): Remove this once tox
uses isolated builds.
-testPy38Cython.mustRunAfter testPython38, testPy38CloudCoverage
// PyCoverage Precommit runs test suites that evaluate test coverage and
compatibility of
diff --git a/sdks/python/test-suites/tox/py39/build.gradle
b/sdks/python/test-suites/tox/py39/build.gradle
index 380cc1486da..5bb73b60a5d 100644
--- a/sdks/python/test-suites/tox/py39/build.gradle
+++ b/sdks/python/test-suites/tox/py39/build.gradle
@@ -27,6 +27,3 @@ applyPythonNature()
pythonVersion = '3.9'
apply from: "../common.gradle"
-
-// TODO(https://github.com/apache/beam/issues/20051): Remove this once tox
uses isolated builds.
-testPy39Cython.mustRunAfter testPython39, testPy39Cloud
diff --git a/sdks/python/tox.ini b/sdks/python/tox.ini
index 1caf25caf08..1e797d96074 100644
--- a/sdks/python/tox.ini
+++ b/sdks/python/tox.ini
@@ -17,7 +17,7 @@
[tox]
# new environments will be excluded by default unless explicitly added to
envlist.
-envlist =
py38,py39,py310,py311,py38-{cloud,cython,docs,lint,mypy,cloudcoverage,dask},py39-{cloud,cython},py310-{cloud,cython,dask},py311-{cloud,cython,dask},whitespacelint
+envlist =
py38,py39,py310,py311,py38-{cloud,docs,lint,mypy,cloudcoverage,dask},py39-{cloud},py310-{cloud,dask},py311-{cloud,dask},whitespacelint
toxworkdir = {toxinidir}/target/{env:ENV_NAME:.tox}
[pycodestyle]
@@ -44,9 +44,6 @@ allowlist_externals =
curl
./codecov
chmod
-deps =
- cython: cython==0.29.33
- -r build-requirements.txt
setenv =
RUN_SKIPPED_PY3_TESTS=0
# Use an isolated tmp dir for tests that get slowed down by scanning /tmp.
@@ -67,6 +64,7 @@ commands_pre =
bash {toxinidir}/scripts/run_tox_cleanup.sh
commands_post =
bash {toxinidir}/scripts/run_tox_cleanup.sh
+
commands = false {envname} is misconfigured
[testenv:py{38,39,310,311}]
@@ -81,28 +79,18 @@ commands =
install_command = {envbindir}/python.exe {envbindir}/pip.exe install --retries
10 {opts} {packages}
list_dependencies_command = {envbindir}/python.exe {envbindir}/pip.exe freeze
-[testenv:py{38,39,310,311}-cython]
-# cython tests are only expected to work in linux (2.x and 3.x)
-# If we want to add other platforms in the future, it should be:
-# `platform = linux2|darwin|...`
-# See https://docs.python.org/2/library/sys.html#sys.platform for platform
codes
-platform = linux
-commands =
- # TODO(https://github.com/apache/beam/issues/20051): Remove this build_ext
invocation once local source no longer
- # shadows the installed apache_beam.
- python setup.py build_ext --inplace
- python apache_beam/examples/complete/autocomplete_test.py
- bash {toxinidir}/scripts/run_pytest.sh {envname} "{posargs}"
-
[testenv:py{38,39,310,311}-cloud]
+; extras = test,gcp,interactive,dataframe,aws,azure
extras = test,gcp,interactive,dataframe,aws,azure
commands =
+ python apache_beam/examples/complete/autocomplete_test.py
bash {toxinidir}/scripts/run_pytest.sh {envname} "{posargs}"
[testenv:py{38,39,310,311}-dask]
extras = test,dask
commands =
bash {toxinidir}/scripts/run_pytest.sh {envname} "{posargs}"
+
[testenv:py38-cloudcoverage]
deps =
pytest-cov==3.0.0
@@ -124,7 +112,6 @@ commands =
setenv =
# keep the version of pylint in sync with the 'rev' in .pre-commit-config.yaml
deps =
- -r build-requirements.txt
astroid<2.17.0,>=2.15.6
pycodestyle==2.8.0
pylint==2.17.5
@@ -143,7 +130,6 @@ commands =
[testenv:py38-mypy]
deps =
- -r build-requirements.txt
mypy==0.790
dask==2022.01.0
distributed==2022.01.0
@@ -173,7 +159,6 @@ commands =
# Used by hdfs_integration_test.sh. Do not run this directly, as it depends on
# nodes defined in hdfs_integration_test/docker-compose.yml.
deps =
- -r build-requirements.txt
holdup==1.8.0
extras =
gcp
@@ -206,7 +191,6 @@ commands_pre =
# Do not run this directly, as it depends on nodes defined in
# azure/integration_test/docker-compose.yml.
deps =
- -r build-requirements.txt
extras =
azure
passenv = REQUESTS_CA_BUNDLE
@@ -335,7 +319,6 @@ commands =
[testenv:py{38,39,310,311}-pytorch-{19,110,111,112,113}]
deps =
- -r build-requirements.txt
19: torch>=1.9.0,<1.10.0
110: torch>=1.10.0,<1.11.0
111: torch>=1.11.0,<1.12.0
@@ -353,7 +336,6 @@ commands =
[testenv:py{38,39,310}-pytorch-200]
deps =
- -r build-requirements.txt
200: torch>=2.0.0,<2.1.0
extras = test,gcp
# Don't set TMPDIR to avoid "AF_UNIX path too long" errors in certain tests.
@@ -387,7 +369,6 @@ commands =
[testenv:py{38,39,310}-tensorflow-212]
deps =
- -r build-requirements.txt
212: tensorflow>=2.12rc1,<2.13
extras = test,gcp
commands =
@@ -399,7 +380,6 @@ commands =
[testenv:py{38,39,310}-xgboost-{160,170}]
deps =
- -r build-requirements.txt
160:
xgboost>=1.6.0,<1.7.0
datatable==1.0.0
@@ -416,7 +396,6 @@ commands =
[testenv:py{38,39,310,311}-transformers-{428,429,430}]
deps =
- -r build-requirements.txt
428: transformers>=4.28.0,<4.29.0
429: transformers>=4.29.0,<4.30.0
430: transformers>=4.30.0,<4.31.0
@@ -434,7 +413,6 @@ commands =
[testenv:py{38,311}-vertex-ai]
deps =
- -r build-requirements.txt
tensorflow==2.12.0
extras = test,gcp
commands =
diff --git
a/website/www/site/content/en/documentation/ml/multi-language-inference.md
b/website/www/site/content/en/documentation/ml/multi-language-inference.md
index 0d7a972e076..1480b37ab48 100644
--- a/website/www/site/content/en/documentation/ml/multi-language-inference.md
+++ b/website/www/site/content/en/documentation/ml/multi-language-inference.md
@@ -99,7 +99,7 @@ Finally, we postprocess the model predictions in the
`Postprocess` DoFn. The `Po
The custom Python code needs to be written in a local package and be compiled
as a tarball. This package can then be used by the Java pipeline. The following
example shows how to compile the Python package into a tarball:
```bash
- python setup.py sdist
+ pip install --upgrade build && python -m build --sdist
```
In order to run this, a `setup.py` is required. The path to the tarball will
be used as an argument in the pipeline options of the Java pipeline.
diff --git
a/website/www/site/content/en/documentation/sdks/python-pipeline-dependencies.md
b/website/www/site/content/en/documentation/sdks/python-pipeline-dependencies.md
index 378032ab6b5..c99c0b9c7cf 100644
---
a/website/www/site/content/en/documentation/sdks/python-pipeline-dependencies.md
+++
b/website/www/site/content/en/documentation/sdks/python-pipeline-dependencies.md
@@ -66,16 +66,17 @@ If your pipeline uses packages that are not available
publicly (e.g. packages th
This command lists all packages that are installed on your machine,
regardless of where they were installed from.
-2. Run your pipeline with the following command-line option:
+ 1. Run your pipeline with the following command-line option:
- --extra_package /path/to/package/package-name
+ --extra_package /path/to/package/package-name
- where package-name is the package's tarball. If you have the `setup.py` for
that
- package then you can build the tarball with the following command:
+ where package-name is the package's tarball. You can build the package
tarball using a command line tool called
[build](https://setuptools.pypa.io/en/latest/userguide/quickstart.html#install-build).
- python setup.py sdist
+ # Install build using pip
+ pip install --upgrade build
+ python -m build --sdist
- See the [sdist
documentation](https://docs.python.org/3/distutils/sourcedist.html) for more
details on this command.
+ See the [build
documentation](https://pypa-build.readthedocs.io/en/latest/index.html) for more
details on this command.
## Multiple File Dependencies