diff --git a/.github/workflows/CD-publish_to_pypi.yml b/.github/workflows/CD-publish_to_pypi.yml index c6cdf887..fd6e3714 100644 --- a/.github/workflows/CD-publish_to_pypi.yml +++ b/.github/workflows/CD-publish_to_pypi.yml @@ -1,54 +1,65 @@ name: CD | Publish Python 🐍 distributions 📦 to PyPI on: - release: - types: [published] - + push: + branches: + - main workflow_dispatch: +permissions: + contents: write + pull-requests: write + actions: write + jobs: + release-please: + runs-on: ubuntu-latest + outputs: + release_created: ${{ steps.release.outputs.release_created }} + tag_name: ${{ steps.release.outputs.tag_name }} + steps: + - uses: google-github-actions/release-please-action@v3 + id: release + with: + token: ${{ secrets.GITHUB_TOKEN }} + release-type: python + package-name: runpod + build-n-publish: name: Build and publish Python 🐍 distributions 📦 to PyPI + needs: release-please + if: ${{ needs.release-please.outputs.release_created }} runs-on: ubuntu-latest + environment: release + permissions: + contents: read + id-token: write # Required for OIDC steps: - uses: actions/checkout@v4 - - name: Set up Python 3.11.10 - uses: actions/setup-python@v5 + - name: Install uv + uses: astral-sh/setup-uv@v6 with: - python-version: 3.11.10 + enable-cache: true - - name: Install pypa/build - run: >- - python -m - pip install - build - --user + - name: Set up Python 3.11.10 + run: uv python install 3.11.10 - - name: Build a binary wheel and a source tarball - run: >- - python -m - build - --sdist - --wheel - --outdir dist/ - . + - name: Build package + run: uv build - name: Publish distribution 📦 to Test PyPI uses: pypa/gh-action-pypi-publish@release/v1 with: - password: ${{ secrets.TEST_PYPI_API_TOKEN }} - repository_url: https://test.pypi.org/legacy/ + repository-url: https://test.pypi.org/legacy/ - name: Publish distribution 📦 to PyPI - # if: startsWith(github.ref, 'refs/tags') uses: pypa/gh-action-pypi-publish@release/v1 - with: - password: ${{ secrets.PYPI_API_TOKEN }} notify-runpod-workers: name: Notify workers - needs: build-n-publish + needs: [release-please, build-n-publish] + if: ${{ needs.release-please.outputs.release_created }} strategy: matrix: repo: @@ -75,7 +86,7 @@ jobs: runs-on: ubuntu-latest steps: - - name: Wait for propegation + - name: Wait for propagation run: sleep 300s shell: bash diff --git a/.github/workflows/CD-test_publish_to_pypi.yml b/.github/workflows/CD-test_publish_to_pypi.yml index 308522bc..390fea0b 100644 --- a/.github/workflows/CD-test_publish_to_pypi.yml +++ b/.github/workflows/CD-test_publish_to_pypi.yml @@ -11,32 +11,25 @@ jobs: build-n-publish: name: Build and publish Python 🐍 distributions 📦 to TestPyPI runs-on: ubuntu-latest + environment: test-release + permissions: + contents: read + id-token: write # Required for OIDC steps: - uses: actions/checkout@v4 - - name: Set up Python 3.11.10 - uses: actions/setup-python@v5 + - name: Install uv + uses: astral-sh/setup-uv@v6 with: - python-version: 3.11.10 + enable-cache: true - - name: Install pypa/build - run: >- - python -m - pip install - build - --user + - name: Set up Python 3.11.10 + run: uv python install 3.11.10 - - name: Build a binary wheel and a source tarball - run: >- - python -m - build - --sdist - --wheel - --outdir dist/ - . + - name: Build package + run: uv build - name: Publish distribution 📦 to Test PyPI uses: pypa/gh-action-pypi-publish@release/v1 with: - password: ${{ secrets.TEST_PYPI_API_TOKEN }} - repository_url: https://test.pypi.org/legacy/ + repository-url: https://test.pypi.org/legacy/ diff --git a/.github/workflows/CI-codeql.yml b/.github/workflows/CI-codeql.yml index aa1e8b56..1ce26cfd 100644 --- a/.github/workflows/CI-codeql.yml +++ b/.github/workflows/CI-codeql.yml @@ -45,12 +45,7 @@ jobs: uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - - # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs - # queries: security-extended,security-and-quality + queries: security-extended,security-and-quality # Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java). # If this step fails, then you should remove it and run the build manually (see below) diff --git a/.github/workflows/CI-e2e.yml b/.github/workflows/CI-e2e.yml index a08f4f81..9c1ec013 100644 --- a/.github/workflows/CI-e2e.yml +++ b/.github/workflows/CI-e2e.yml @@ -52,16 +52,17 @@ jobs: - name: Set Docker Tag as Output id: output_docker_tag - run: echo "::set-output name=docker_tag::${{ env.DOCKER_TAG }}" + run: echo "docker_tag=${{ env.DOCKER_TAG }}" >> $GITHUB_OUTPUT - name: Build and push Docker image - env: - DOCKERHUB_REPO: ${{ vars.DOCKERHUB_REPO }} - DOCKERHUB_IMG: ${{ vars.DOCKERHUB_IMG }} - run: | - docker login -u ${{ secrets.DOCKERHUB_USERNAME }} -p ${{ secrets.DOCKERHUB_TOKEN }} - docker build -t $DOCKERHUB_REPO/$DOCKERHUB_IMG:${{ env.DOCKER_TAG }} -f mock-worker/Dockerfile mock-worker - docker push $DOCKERHUB_REPO/$DOCKERHUB_IMG:${{ env.DOCKER_TAG }} + uses: docker/build-push-action@v6 + with: + context: ./mock-worker + file: ./mock-worker/Dockerfile + push: true + tags: ${{ vars.DOCKERHUB_REPO }}/${{ vars.DOCKERHUB_IMG }}:${{ env.DOCKER_TAG }} + cache-from: type=gha + cache-to: type=gha,mode=max test: name: Run End-to-End Tests diff --git a/.github/workflows/CI-pytests.yml b/.github/workflows/CI-pytests.yml index bc78f6d4..5be856a9 100644 --- a/.github/workflows/CI-pytests.yml +++ b/.github/workflows/CI-pytests.yml @@ -21,15 +21,16 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 + - name: Install uv + uses: astral-sh/setup-uv@v6 with: - python-version: ${{ matrix.python-version }} + enable-cache: true + + - name: Set up Python ${{ matrix.python-version }} + run: uv python install ${{ matrix.python-version }} - name: Install Dependencies - run: | - python -m pip install --upgrade pip - pip install '.[test]' + run: uv sync --group test - name: Run Tests - run: pytest + run: uv run pytest diff --git a/.github/workflows/vhs.yml b/.github/workflows/vhs.yml index 9921509f..ae34d94b 100644 --- a/.github/workflows/vhs.yml +++ b/.github/workflows/vhs.yml @@ -12,9 +12,16 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Install uv + uses: astral-sh/setup-uv@v6 + with: + enable-cache: true + + - name: Set up Python 3.11 + run: uv python install 3.11 + - name: Install runpod - run: | - pip install . + run: uv sync # runpod --help - uses: charmbracelet/vhs-action@v2 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b8c35b2f..af0be9cd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -35,6 +35,11 @@ Here is a quick guide on how to contribute code to this project: 6. Run tests to ensure that your changes do not break any existing functionality. You can run tests using the following command: ```bash + # Using uv (recommended - faster) + uv sync --group test + uv run pytest + + # Or using pip pip install '.[test]' pytest ``` diff --git a/README.md b/README.md index 7972eeb6..7a99b693 100644 --- a/README.md +++ b/README.md @@ -7,8 +7,6 @@ [![CI | End-to-End Runpod Python Tests](https://github.com/runpod/runpod-python/actions/workflows/CI-e2e.yml/badge.svg)](https://github.com/runpod/runpod-python/actions/workflows/CI-e2e.yml) -[![CI | Code Quality](https://github.com/runpod/runpod-python/actions/workflows/CI-pylint.yml/badge.svg)](https://github.com/runpod/runpod-python/actions/workflows/CI-pylint.yml) -  [![CI | Unit Tests](https://github.com/runpod/runpod-python/actions/workflows/CI-pytests.yml/badge.svg)](https://github.com/runpod/runpod-python/actions/workflows/CI-pytests.yml)   [![CI | CodeQL](https://github.com/runpod/runpod-python/actions/workflows/CI-codeql.yml/badge.svg)](https://github.com/runpod/runpod-python/actions/workflows/CI-codeql.yml) @@ -36,10 +34,14 @@ Welcome to the official Python library for Runpod API & SDK. # Install the latest release version pip install runpod -# or +# Using uv (faster alternative) +uv add runpod # Install the latest development version (main branch) pip install git+https://github.com/runpod/runpod-python.git + +# Or with uv +uv add git+https://github.com/runpod/runpod-python.git ``` *Python 3.8 or higher is required to use the latest version of this package.* diff --git a/pyproject.toml b/pyproject.toml index 30f24c08..abf416c2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -49,7 +49,7 @@ version_file = "runpod/_version.py" runpod = "runpod.cli.entry:runpod_cli" -[project.optional-dependencies] +[dependency-groups] test = [ "asynctest", "nest_asyncio", diff --git a/pytest.ini b/pytest.ini index 68e2f208..1b234a21 100644 --- a/pytest.ini +++ b/pytest.ini @@ -2,3 +2,4 @@ addopts = --durations=10 --cov-config=.coveragerc --timeout=120 --timeout_method=thread --cov=runpod --cov-report=xml --cov-report=term-missing --cov-fail-under=90 -W error -p no:cacheprovider -p no:unraisableexception python_files = tests.py test_*.py *_test.py norecursedirs = venv *.egg-info .git build +asyncio_mode = auto diff --git a/tests/test_serverless/test_modules/test_fastapi.py b/tests/test_serverless/test_modules/test_fastapi.py index a140dc0e..9b27139f 100644 --- a/tests/test_serverless/test_modules/test_fastapi.py +++ b/tests/test_serverless/test_modules/test_fastapi.py @@ -90,7 +90,6 @@ def test_run(self): """ Tests the _run() method. """ - loop = asyncio.get_event_loop() module_location = "runpod.serverless.modules.rp_fastapi" with patch( @@ -133,14 +132,12 @@ def generator_handler(job): ) assert generator_run_return == {"id": "test-123", "status": "IN_PROGRESS"} - loop.close() @pytest.mark.asyncio def test_runsync(self): """ Tests the _runsync() method. """ - loop = asyncio.get_event_loop() module_location = "runpod.serverless.modules.rp_fastapi" with patch(f"{module_location}.FastAPI", Mock()), patch( @@ -195,14 +192,12 @@ def generator_handler(job): asyncio.run(worker_api._sim_runsync(input_object_with_webhook)) assert mock_threading.Thread.called - loop.close() @pytest.mark.asyncio def test_stream(self): """ Tests the _stream() method. """ - loop = asyncio.get_event_loop() module_location = "runpod.serverless.modules.rp_fastapi" with patch(f"{module_location}.FastAPI", Mock()), patch( @@ -260,14 +255,12 @@ def generator_handler(job): asyncio.run(generator_worker_api._sim_stream("test-123")) assert mock_threading.Thread.called - loop.close() @pytest.mark.asyncio def test_status(self): """ Tests the _status() method. """ - loop = asyncio.get_event_loop() module_location = "runpod.serverless.modules.rp_fastapi" with patch(f"{module_location}.FastAPI", Mock()), patch( @@ -332,4 +325,3 @@ def generator_handler(job): error_status_return = asyncio.run(error_worker_api._sim_status("test-123")) assert "error" in error_status_return - loop.close()