Skip to content

Commit d71bb11

Browse files
[Vast.ai] Allow to set community_cloud to false (#218)
1 parent ae2f67a commit d71bb11

2 files changed

Lines changed: 35 additions & 3 deletions

File tree

src/gpuhunt/providers/vastai.py

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,20 @@
2121
class VastAIProvider(AbstractProvider):
2222
NAME = "vastai"
2323

24-
def __init__(self, extra_filters: Optional[dict[str, dict[Operators, FilterValue]]] = None):
24+
def __init__(
25+
self,
26+
extra_filters: Optional[dict[str, dict[Operators, FilterValue]]] = None,
27+
community_cloud: bool = True,
28+
):
2529
self.extra_filters = extra_filters
30+
self.community_cloud = community_cloud
2631

2732
def get(
2833
self, query_filter: Optional[QueryFilter] = None, balance_resources: bool = True
2934
) -> list[RawCatalogItem]:
30-
filters: dict[str, Any] = self.make_filters(query_filter or QueryFilter())
35+
filters: dict[str, Any] = self.make_filters(
36+
query_filter or QueryFilter(), community_cloud=self.community_cloud
37+
)
3138
if self.extra_filters:
3239
for key, constraints in self.extra_filters.items():
3340
for op, value in constraints.items():
@@ -79,7 +86,9 @@ def get(
7986
return instance_offers
8087

8188
@staticmethod
82-
def make_filters(q: QueryFilter) -> dict[str, dict[Operators, FilterValue]]:
89+
def make_filters(
90+
q: QueryFilter, community_cloud: bool = True
91+
) -> dict[str, dict[Operators, FilterValue]]:
8392
filters = defaultdict(dict)
8493
if q.min_cpu is not None:
8594
filters["cpu_cores"]["gte"] = q.min_cpu
@@ -120,6 +129,11 @@ def make_filters(q: QueryFilter) -> dict[str, dict[Operators, FilterValue]]:
120129
filters["compute_capability"]["gte"] = compute_cap(q.min_compute_capability)
121130
if q.max_compute_capability is not None:
122131
filters["compute_capability"]["lte"] = compute_cap(q.max_compute_capability)
132+
# Datacenter offers map to Vast's "server cloud" scope.
133+
# When community_cloud is enabled, keep scope unfiltered so both
134+
# server and community offers are returned.
135+
if not community_cloud:
136+
filters["datacenter"]["eq"] = True
123137
filters["rentable"]["eq"] = True
124138
filters["rented"]["eq"] = False
125139
filters["order"] = [["score", "desc"]]
@@ -128,6 +142,10 @@ def make_filters(q: QueryFilter) -> dict[str, dict[Operators, FilterValue]]:
128142
@staticmethod
129143
def satisfies_filters(offer: dict, filters: dict[str, dict[Operators, FilterValue]]) -> bool:
130144
for key in filters:
145+
# `datacenter`/`external` are query scope controls.
146+
# They don't map to offer fields with strict eq semantics.
147+
if key in {"datacenter", "external"}:
148+
continue
131149
if key not in offer:
132150
continue
133151
for op, value in filters[key].items():

src/tests/providers/test_vastai.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from gpuhunt._internal.models import QueryFilter
2+
from gpuhunt.providers.vastai import VastAIProvider
3+
4+
5+
def test_make_filters_defaults_to_datacenter_only():
6+
filters = VastAIProvider.make_filters(QueryFilter(), community_cloud=False)
7+
assert filters["datacenter"]["eq"] is True
8+
assert "external" not in filters
9+
10+
11+
def test_make_filters_does_not_constrain_scope_when_community_cloud_enabled():
12+
filters = VastAIProvider.make_filters(QueryFilter(), community_cloud=True)
13+
assert "datacenter" not in filters
14+
assert "external" not in filters

0 commit comments

Comments
 (0)