Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ['3.10', '3.11', '3.12']
python-version: ['3.10', '3.11', '3.12', '3.13']
timeout-minutes: 15

steps:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release-please.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ['3.10', '3.11', '3.12']
python-version: ['3.10', '3.11', '3.12', '3.13']
timeout-minutes: 15

steps:
Expand Down
6 changes: 5 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,14 @@ license = { text = "MIT" }
classifiers = [
"Development Status :: 4 - Beta",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
]
requires-python = ">=3.10,<3.13"
requires-python = ">=3.10,<3.14"
Comment thread
deanq marked this conversation as resolved.

dependencies = [
"cloudpickle>=3.1.1",
Expand Down
13 changes: 7 additions & 6 deletions src/runpod_flash/core/resources/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,20 @@

# Worker runtime Python versions. One tarball serves every resource in an app,
# so all resources must share a single Python version. GPU images ship 3.12
# with torch pre-installed; 3.10 and 3.11 are available via side-by-side
# install (~7 GB alt-Python overhead) in the same base image.
# with torch pre-installed; 3.10, 3.11, and 3.13 are available via side-by-side
# install (deadsnakes PPA) in the same base image.
WORKER_PYTHON_VERSION: str = "3.12"
GPU_PYTHON_VERSIONS: tuple[str, ...] = ("3.10", "3.11", "3.12")
CPU_PYTHON_VERSIONS: tuple[str, ...] = ("3.10", "3.11", "3.12")
GPU_PYTHON_VERSIONS: tuple[str, ...] = ("3.10", "3.11", "3.12", "3.13")
CPU_PYTHON_VERSIONS: tuple[str, ...] = ("3.10", "3.11", "3.12", "3.13")

# Base image ships 3.12 with torch pre-installed; non-3.12 targets reinstall
# torch side-by-side for the selected interpreter.
# torch side-by-side for the selected interpreter. 3.13 is provided via
# deadsnakes PPA in the worker image.
GPU_BASE_IMAGE_PYTHON_VERSION: str = "3.12"
DEFAULT_PYTHON_VERSION: str = "3.12"

# Python versions that can run the flash SDK locally (for flash build, etc.)
SUPPORTED_PYTHON_VERSIONS: tuple[str, ...] = ("3.10", "3.11", "3.12")
SUPPORTED_PYTHON_VERSIONS: tuple[str, ...] = ("3.10", "3.11", "3.12", "3.13")


def local_python_version() -> str:
Expand Down
6 changes: 6 additions & 0 deletions tests/unit/cli/commands/build_utils/test_manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -1053,3 +1053,9 @@ def test_unsupported_override_raises(self):
def test_unsupported_resource_version_raises(self):
with pytest.raises(ValueError, match="not supported"):
self._builder()._reconcile_python_version(_make_resources_dict(gpu="3.8"))

def test_reconcile_python_version_accepts_3_13_declaration(self):
resolved = self._builder()._reconcile_python_version(
_make_resources_dict(gpu="3.13")
)
assert resolved == "3.13"
23 changes: 14 additions & 9 deletions tests/unit/core/resources/test_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@

class TestSupportedPythonVersions:
def test_supported_versions(self):
assert SUPPORTED_PYTHON_VERSIONS == ("3.10", "3.11", "3.12")
assert SUPPORTED_PYTHON_VERSIONS == ("3.10", "3.11", "3.12", "3.13")

def test_gpu_python_versions(self):
assert GPU_PYTHON_VERSIONS == ("3.10", "3.11", "3.12")
assert GPU_PYTHON_VERSIONS == ("3.10", "3.11", "3.12", "3.13")

def test_cpu_python_versions(self):
assert CPU_PYTHON_VERSIONS == ("3.10", "3.11", "3.12")
assert CPU_PYTHON_VERSIONS == ("3.10", "3.11", "3.12", "3.13")

def test_default_python_version_is_3_12(self):
assert DEFAULT_PYTHON_VERSION == "3.12"
Expand All @@ -40,28 +40,33 @@ def test_gpu_3_12(self):
get_image_name("gpu", "3.12", tag="latest") == "runpod/flash:py3.12-latest"
)

@pytest.mark.parametrize("version", ["3.10", "3.11", "3.12"])
def test_gpu_3_13(self):
assert (
get_image_name("gpu", "3.13", tag="latest") == "runpod/flash:py3.13-latest"
)

@pytest.mark.parametrize("version", ["3.10", "3.11", "3.12", "3.13"])
def test_gpu_all_supported_versions(self, version):
assert (
get_image_name("gpu", version, tag="latest")
== f"runpod/flash:py{version}-latest"
)

@pytest.mark.parametrize("version", ["3.10", "3.11", "3.12"])
@pytest.mark.parametrize("version", ["3.10", "3.11", "3.12", "3.13"])
def test_cpu_all_supported_versions(self, version):
assert (
get_image_name("cpu", version, tag="latest")
== f"runpod/flash-cpu:py{version}-latest"
)

@pytest.mark.parametrize("version", ["3.10", "3.11", "3.12"])
@pytest.mark.parametrize("version", ["3.10", "3.11", "3.12", "3.13"])
def test_lb_all_supported_versions(self, version):
assert (
get_image_name("lb", version, tag="latest")
== f"runpod/flash-lb:py{version}-latest"
)

@pytest.mark.parametrize("version", ["3.10", "3.11", "3.12"])
@pytest.mark.parametrize("version", ["3.10", "3.11", "3.12", "3.13"])
def test_lb_cpu_all_supported_versions(self, version):
assert (
get_image_name("lb-cpu", version, tag="latest")
Expand All @@ -82,7 +87,7 @@ def test_invalid_image_type_raises(self):

def test_invalid_python_version_raises(self):
with pytest.raises(ValueError, match="not supported"):
get_image_name("gpu", "3.13")
get_image_name("gpu", "3.9")

def test_custom_tag(self):
assert get_image_name("gpu", "3.12", tag="v2.0") == "runpod/flash:py3.12-v2.0"
Expand Down Expand Up @@ -128,7 +133,7 @@ def test_valid_versions(self):

def test_invalid_version_raises(self):
with pytest.raises(ValueError, match="not supported"):
validate_python_version("3.13")
validate_python_version("3.99")

def test_old_version_raises(self):
with pytest.raises(ValueError, match="not supported"):
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/resources/test_serverless.py
Original file line number Diff line number Diff line change
Expand Up @@ -2429,7 +2429,7 @@ def test_python_version_accepts_valid_values(self):
def test_python_version_rejects_invalid(self):
with pytest.raises(ValueError, match="not supported"):
ServerlessEndpoint(
name="test", imageName="test:latest", python_version="3.13"
name="test", imageName="test:latest", python_version="3.99"
)

def test_python_version_rejects_3_9(self):
Expand Down
Loading