Skip to content
Merged
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
3 changes: 2 additions & 1 deletion src/runpod_flash/core/resources/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
)
from .serverless_cpu import CpuServerlessEndpoint
from .template import PodTemplate
from .network_volume import NetworkVolume, DataCenter, CPU_DATACENTERS
from .network_volume import NetworkVolume
from .datacenter import DataCenter, CPU_DATACENTERS
from .load_balancer_sls_resource import (
CpuLoadBalancerSlsResource,
LoadBalancerSlsResource,
Expand Down
52 changes: 52 additions & 0 deletions src/runpod_flash/core/resources/datacenter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
from enum import Enum


class DataCenter(str, Enum):
"""Enum representing available RunPod data centers.

NOTE: these are only datacenters with storage support, and S3 API support.
"""

# north america
US_CA_2 = "US-CA-2"
US_IL_1 = "US-IL-1"
US_KS_2 = "US-KS-2"
US_MO_1 = "US-MO-1"
US_MO_2 = "US-MO-2"
US_NC_2 = "US-NC-2"
US_NE_1 = "US-NE-1"
US_WA_1 = "US-WA-1"

# europe
EU_CZ_1 = "EU-CZ-1"
EU_RO_1 = "EU-RO-1"
EUR_NO_1 = "EUR-NO-1"
Comment thread
KAJdev marked this conversation as resolved.

@classmethod
def from_string(cls, value: str) -> "DataCenter":
"""Parse a datacenter ID string into a DataCenter enum.

Accepts the canonical form (e.g. "EU-RO-1") as well as common
variations like lowercase or underscore-separated.
"""
normalized = value.strip().upper().replace("_", "-")
try:
return cls(normalized)
except ValueError:
valid = ", ".join(dc.value for dc in cls)
raise ValueError(
f"Unknown datacenter '{value}'. Valid datacenters: {valid}"
)
Comment thread
KAJdev marked this conversation as resolved.

@classmethod
def all(cls) -> list["DataCenter"]:
"""Return all datacenters."""
return list(cls)
Comment thread
KAJdev marked this conversation as resolved.


# data centers that support CPU serverless endpoints
CPU_DATACENTERS: frozenset[DataCenter] = frozenset(
{
DataCenter.EU_RO_1,
}
)
49 changes: 1 addition & 48 deletions src/runpod_flash/core/resources/network_volume.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import hashlib
import logging
from enum import Enum
from typing import Optional, Dict, Any

from pydantic import (
Expand All @@ -10,6 +9,7 @@
field_serializer,
model_validator,
)
from .datacenter import DataCenter
Comment thread
KAJdev marked this conversation as resolved.

from ..api.runpod import RunpodRestClient
from ..urls import RUNPOD_CONSOLE_URL
Expand All @@ -19,53 +19,6 @@
log = logging.getLogger(__name__)


class DataCenter(str, Enum):
"""Enum representing available RunPod data centers."""

# north america
US_CA_2 = "US-CA-2"
US_GA_2 = "US-GA-2"
US_IL_1 = "US-IL-1"
US_KS_2 = "US-KS-2"
US_MD_1 = "US-MD-1"
US_MO_1 = "US-MO-1"
US_MO_2 = "US-MO-2"
US_NC_1 = "US-NC-1"
US_NC_2 = "US-NC-2"
US_NE_1 = "US-NE-1"
US_WA_1 = "US-WA-1"

# europe
EU_CZ_1 = "EU-CZ-1"
EU_RO_1 = "EU-RO-1"
EUR_IS_1 = "EUR-IS-1"
EUR_NO_1 = "EUR-NO-1"

@classmethod
def from_string(cls, value: str) -> "DataCenter":
"""Parse a datacenter ID string into a DataCenter enum.

Accepts the canonical form (e.g. "EU-RO-1") as well as common
variations like lowercase or underscore-separated.
"""
normalized = value.strip().upper().replace("_", "-")
try:
return cls(normalized)
except ValueError:
valid = ", ".join(dc.value for dc in cls)
raise ValueError(
f"Unknown datacenter '{value}'. Valid datacenters: {valid}"
)


# data centers that support CPU serverless endpoints
CPU_DATACENTERS: frozenset[DataCenter] = frozenset(
{
DataCenter.EU_RO_1,
}
)


class NetworkVolume(DeployableResource):
"""
NetworkVolume resource for creating and managing Runpod network volumes.
Expand Down
3 changes: 2 additions & 1 deletion src/runpod_flash/core/resources/serverless.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@
)
from .cpu import CpuInstanceType
from .gpu import GpuGroup, GpuType
from .network_volume import NetworkVolume, DataCenter, CPU_DATACENTERS
from .network_volume import NetworkVolume
from .datacenter import DataCenter, CPU_DATACENTERS
from .request_logs import QBRequestLogBatch, QBRequestLogFetcher, QBRequestLogPhase
from .worker_availability_diagnostic import WorkerAvailabilityDiagnostic
from .template import KeyValuePair, PodTemplate
Expand Down
15 changes: 12 additions & 3 deletions src/runpod_flash/endpoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
from .core.resources.constants import DEFAULT_WORKERS_MAX, DEFAULT_WORKERS_MIN
from .core.resources.cpu import CpuInstanceType
from .core.resources.gpu import GpuGroup, GpuType
from .core.resources.network_volume import DataCenter, NetworkVolume
from .core.resources.network_volume import NetworkVolume
from .core.resources.datacenter import DataCenter
from .core.resources.serverless import CudaVersion, ServerlessScalerType
from .core.resources.template import PodTemplate

Expand Down Expand Up @@ -463,10 +464,18 @@ def __init__(
self.template = template
self.min_cuda_version = min_cuda_version

# if no gpu or cpu specified, default to gpu any (unless pure client mode)
if not self._is_cpu and self._gpu is None and not self.is_client:
# if no gpu or cpu specified, default to gpu any. image= still provisions
# a new endpoint, so only id-only clients (connecting to an existing
# endpoint) skip this defaulting.
if not self._is_cpu and self._gpu is None and self.id is None:
self._gpu = [GpuGroup.ANY]

# make sure default datacenters are set when provisioning a new endpoint.
# image= still provisions, so only id-only clients skip this. not CPU
# though, that gets pinned to specific datacenters.
if not self._is_cpu and self.id is None and not self.datacenter:
self.datacenter = DataCenter.all()

# lb routes registered via .get()/.post()/etc (decorator mode only)
self._routes: List[Dict[str, Any]] = []

Expand Down
10 changes: 4 additions & 6 deletions tests/unit/cli/commands/build_utils/test_manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -481,8 +481,7 @@ def test_extract_deployment_config_includes_network_volume():

resource_py = project_dir / "resource.py"
resource_py.write_text(
"from runpod_flash import NetworkVolume\n"
"from runpod_flash.core.resources.network_volume import DataCenter\n"
"from runpod_flash import NetworkVolume, DataCenter\n"
"\n"
"class gpu_config:\n"
' imageName = "test-image"\n'
Expand Down Expand Up @@ -599,8 +598,7 @@ def test_extract_deployment_config_includes_network_volumes():

resource_py = project_dir / "resource.py"
resource_py.write_text(
"from runpod_flash import NetworkVolume\n"
"from runpod_flash.core.resources.network_volume import DataCenter\n"
"from runpod_flash import NetworkVolume, DataCenter\n"
"\n"
"class gpu_config:\n"
' imageName = "test-image"\n'
Expand All @@ -613,7 +611,7 @@ def test_extract_deployment_config_includes_network_volumes():
" NetworkVolume(\n"
' name="vol-us",\n'
" size=200,\n"
" dataCenterId=DataCenter.US_GA_2,\n"
" dataCenterId=DataCenter.US_CA_2,\n"
" ),\n"
" ]\n"
)
Expand Down Expand Up @@ -643,7 +641,7 @@ def test_extract_deployment_config_includes_network_volumes():
assert config["networkVolumes"][0]["dataCenterId"] == "EU-RO-1"
assert config["networkVolumes"][1]["name"] == "vol-us"
assert config["networkVolumes"][1]["size"] == 200
assert config["networkVolumes"][1]["dataCenterId"] == "US-GA-2"
assert config["networkVolumes"][1]["dataCenterId"] == "US-CA-2"
assert "networkVolume" not in config


Expand Down
3 changes: 2 additions & 1 deletion tests/unit/resources/test_network_volume.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
import pytest
from pydantic import ValidationError

from runpod_flash.core.resources.network_volume import NetworkVolume, DataCenter
from runpod_flash.core.resources.network_volume import NetworkVolume
from runpod_flash.core.resources.datacenter import DataCenter


class TestNetworkVolumeIdempotent:
Expand Down
Loading
Loading