From ce3342d8ffa8bec114453975c61f9f6e46e82316 Mon Sep 17 00:00:00 2001 From: Andrew Wang Date: Wed, 22 Apr 2026 17:32:00 +0000 Subject: [PATCH] Update proto and release 0.1.20 --- kagglesdk/__init__.py | 2 +- .../types/benchmark_tasks_api_service.py | 88 +++++++++++++++++ .../competitions/types/hackathon_service.py | 26 ++++- kagglesdk/kaggle_client.py | 2 + .../services/model_proxy_api_service.py | 26 +++++ .../models/types/model_proxy_api_service.py | 99 +++++++++++++++++++ 6 files changed, 237 insertions(+), 6 deletions(-) create mode 100644 kagglesdk/models/services/model_proxy_api_service.py create mode 100644 kagglesdk/models/types/model_proxy_api_service.py diff --git a/kagglesdk/__init__.py b/kagglesdk/__init__.py index 49899af..0b08678 100644 --- a/kagglesdk/__init__.py +++ b/kagglesdk/__init__.py @@ -1,4 +1,4 @@ -__version__ = "0.1.19" +__version__ = "0.1.20" from kagglesdk.kaggle_client import KaggleClient from kagglesdk.kaggle_creds import KaggleCredentials diff --git a/kagglesdk/benchmarks/types/benchmark_tasks_api_service.py b/kagglesdk/benchmarks/types/benchmark_tasks_api_service.py index ef77919..62e0d71 100644 --- a/kagglesdk/benchmarks/types/benchmark_tasks_api_service.py +++ b/kagglesdk/benchmarks/types/benchmark_tasks_api_service.py @@ -735,11 +735,17 @@ class ApiListBenchmarkTasksRequest(KaggleObject): Filter by task creation status (e.g. 'created', 'error'). regex_filter (str) Filter task slugs by regular expression. + page_size (int) + page_token (str) + skip (int) """ def __init__(self): self._status_filter = None self._regex_filter = None + self._page_size = 0 + self._page_token = "" + self._skip = 0 self._freeze() @property @@ -770,6 +776,45 @@ def regex_filter(self, regex_filter: Optional[str]): raise TypeError('regex_filter must be of type str') self._regex_filter = regex_filter + @property + def page_size(self) -> int: + return self._page_size + + @page_size.setter + def page_size(self, page_size: int): + if page_size is None: + del self.page_size + return + if not isinstance(page_size, int): + raise TypeError('page_size must be of type int') + self._page_size = page_size + + @property + def page_token(self) -> str: + return self._page_token + + @page_token.setter + def page_token(self, page_token: str): + if page_token is None: + del self.page_token + return + if not isinstance(page_token, str): + raise TypeError('page_token must be of type str') + self._page_token = page_token + + @property + def skip(self) -> int: + return self._skip + + @skip.setter + def skip(self, skip: int): + if skip is None: + del self.skip + return + if not isinstance(skip, int): + raise TypeError('skip must be of type int') + self._skip = skip + def endpoint(self): path = '/api/v1/benchmarks/tasks/list' return path.format_map(self.to_field_map(self)) @@ -779,10 +824,14 @@ class ApiListBenchmarkTasksResponse(KaggleObject): r""" Attributes: tasks (ApiBenchmarkTask) + total_results (int) + next_page_token (str) """ def __init__(self): self._tasks = [] + self._total_results = 0 + self._next_page_token = "" self._freeze() @property @@ -800,6 +849,40 @@ def tasks(self, tasks: Optional[List[Optional['ApiBenchmarkTask']]]): raise TypeError('tasks must contain only items of type ApiBenchmarkTask') self._tasks = tasks + @property + def total_results(self) -> int: + return self._total_results + + @total_results.setter + def total_results(self, total_results: int): + if total_results is None: + del self.total_results + return + if not isinstance(total_results, int): + raise TypeError('total_results must be of type int') + self._total_results = total_results + + @property + def next_page_token(self) -> str: + return self._next_page_token + + @next_page_token.setter + def next_page_token(self, next_page_token: str): + if next_page_token is None: + del self.next_page_token + return + if not isinstance(next_page_token, str): + raise TypeError('next_page_token must be of type str') + self._next_page_token = next_page_token + + @property + def totalResults(self): + return self.total_results + + @property + def nextPageToken(self): + return self.next_page_token + ApiBatchScheduleBenchmarkTaskRunsRequest._fields = [ FieldMetadata("taskSlugs", "task_slugs", "_task_slugs", ApiBenchmarkTaskSlug, [], ListSerializer(KaggleObjectSerializer())), @@ -871,9 +954,14 @@ def tasks(self, tasks: Optional[List[Optional['ApiBenchmarkTask']]]): ApiListBenchmarkTasksRequest._fields = [ FieldMetadata("statusFilter", "status_filter", "_status_filter", str, None, PredefinedSerializer(), optional=True), FieldMetadata("regexFilter", "regex_filter", "_regex_filter", str, None, PredefinedSerializer(), optional=True), + FieldMetadata("pageSize", "page_size", "_page_size", int, 0, PredefinedSerializer()), + FieldMetadata("pageToken", "page_token", "_page_token", str, "", PredefinedSerializer()), + FieldMetadata("skip", "skip", "_skip", int, 0, PredefinedSerializer()), ] ApiListBenchmarkTasksResponse._fields = [ FieldMetadata("tasks", "tasks", "_tasks", ApiBenchmarkTask, [], ListSerializer(KaggleObjectSerializer())), + FieldMetadata("totalResults", "total_results", "_total_results", int, 0, PredefinedSerializer()), + FieldMetadata("nextPageToken", "next_page_token", "_next_page_token", str, "", PredefinedSerializer()), ] diff --git a/kagglesdk/competitions/types/hackathon_service.py b/kagglesdk/competitions/types/hackathon_service.py index a15fe8f..0d3e684 100644 --- a/kagglesdk/competitions/types/hackathon_service.py +++ b/kagglesdk/competitions/types/hackathon_service.py @@ -1,23 +1,25 @@ from kagglesdk.competitions.types.hackathons import HackathonTrack, HackathonWriteUp from kagglesdk.kaggle_object import * -from typing import List, Optional +from typing import Optional, List class ListHackathonTracksRequest(KaggleObject): r""" Attributes: competition_id (int) + competition_name (str) """ def __init__(self): - self._competition_id = 0 + self._competition_id = None + self._competition_name = None self._freeze() @property def competition_id(self) -> int: - return self._competition_id + return self._competition_id or 0 @competition_id.setter - def competition_id(self, competition_id: int): + def competition_id(self, competition_id: Optional[int]): if competition_id is None: del self.competition_id return @@ -25,6 +27,19 @@ def competition_id(self, competition_id: int): raise TypeError('competition_id must be of type int') self._competition_id = competition_id + @property + def competition_name(self) -> str: + return self._competition_name or "" + + @competition_name.setter + def competition_name(self, competition_name: Optional[str]): + if competition_name is None: + del self.competition_name + return + if not isinstance(competition_name, str): + raise TypeError('competition_name must be of type str') + self._competition_name = competition_name + def endpoint(self): path = '/api/v1/competitions/{competition_id}/hackathon-tracks' return path.format_map(self.to_field_map(self)) @@ -129,7 +144,8 @@ def totalCount(self): ListHackathonTracksRequest._fields = [ - FieldMetadata("competitionId", "competition_id", "_competition_id", int, 0, PredefinedSerializer()), + FieldMetadata("competitionId", "competition_id", "_competition_id", int, None, PredefinedSerializer(), optional=True), + FieldMetadata("competitionName", "competition_name", "_competition_name", str, None, PredefinedSerializer(), optional=True), ] ListHackathonTracksResponse._fields = [ diff --git a/kagglesdk/kaggle_client.py b/kagglesdk/kaggle_client.py index bdf52d3..aacfd1b 100644 --- a/kagglesdk/kaggle_client.py +++ b/kagglesdk/kaggle_client.py @@ -10,6 +10,7 @@ from kagglesdk.education.services.education_api_service import EducationApiClient from kagglesdk.kernels.services.kernels_api_service import KernelsApiClient from kagglesdk.models.services.model_api_service import ModelApiClient +from kagglesdk.models.services.model_proxy_api_service import ModelProxyApiClient from kagglesdk.models.services.model_service import ModelClient from kagglesdk.search.services.search_api_service import SearchApiClient from kagglesdk.security.services.iam_service import IamClient @@ -62,6 +63,7 @@ def __init__(self, http_client: KaggleHttpClient): class Models(object): def __init__(self, http_client: KaggleHttpClient): self.model_api_client = ModelApiClient(http_client) + self.model_proxy_api_client = ModelProxyApiClient(http_client) self.model_client = ModelClient(http_client) class Search(object): diff --git a/kagglesdk/models/services/model_proxy_api_service.py b/kagglesdk/models/services/model_proxy_api_service.py new file mode 100644 index 0000000..6bb1927 --- /dev/null +++ b/kagglesdk/models/services/model_proxy_api_service.py @@ -0,0 +1,26 @@ +from kagglesdk.kaggle_http_client import KaggleHttpClient +from kagglesdk.models.types.model_proxy_api_service import ApiCreateDefaultModelProxyTokenRequest, ApiCreateDefaultModelProxyTokenResponse + +class ModelProxyApiClient(object): + + def __init__(self, client: KaggleHttpClient): + self._client = client + + def create_default_model_proxy_token(self, request: ApiCreateDefaultModelProxyTokenRequest = None) -> ApiCreateDefaultModelProxyTokenResponse: + r""" + Creates a default MP token for local usage. Safety features: + 1) 2h TTL + 2) Requires Persona + Phone verification + 3) Limits model access to 'kaggle-benchmarks-local' + (see cloud/kaggle/modelproxy/backends/config/config.gcl) + 4) Caches requests so each user can only have a single active token + + Args: + request (ApiCreateDefaultModelProxyTokenRequest): + The request object; initialized to empty instance if not specified. + """ + + if request is None: + request = ApiCreateDefaultModelProxyTokenRequest() + + return self._client.call("models.ModelProxyApiService", "CreateDefaultModelProxyToken", request, ApiCreateDefaultModelProxyTokenResponse) diff --git a/kagglesdk/models/types/model_proxy_api_service.py b/kagglesdk/models/types/model_proxy_api_service.py new file mode 100644 index 0000000..fae2c89 --- /dev/null +++ b/kagglesdk/models/types/model_proxy_api_service.py @@ -0,0 +1,99 @@ +from datetime import datetime +from kagglesdk.kaggle_object import * +from typing import Optional + +class ApiCreateDefaultModelProxyTokenRequest(KaggleObject): + r""" + """ + + pass + def endpoint(self): + path = '/api/v1/models/proxy/token' + return path.format_map(self.to_field_map(self)) + + + @staticmethod + def method(): + return 'POST' + + @staticmethod + def body_fields(): + return '*' + + +class ApiCreateDefaultModelProxyTokenResponse(KaggleObject): + r""" + Attributes: + token (str) + Model Proxy token/API key to use for inference requests. + base_uri (str) + Base URL for the proxy (usually 'https://mp-staging.kaggle.net/models'). + expiry_time (datetime) + When the token expires. + """ + + def __init__(self): + self._token = "" + self._base_uri = "" + self._expiry_time = None + self._freeze() + + @property + def token(self) -> str: + """Model Proxy token/API key to use for inference requests.""" + return self._token + + @token.setter + def token(self, token: str): + if token is None: + del self.token + return + if not isinstance(token, str): + raise TypeError('token must be of type str') + self._token = token + + @property + def base_uri(self) -> str: + """Base URL for the proxy (usually 'https://mp-staging.kaggle.net/models').""" + return self._base_uri + + @base_uri.setter + def base_uri(self, base_uri: str): + if base_uri is None: + del self.base_uri + return + if not isinstance(base_uri, str): + raise TypeError('base_uri must be of type str') + self._base_uri = base_uri + + @property + def expiry_time(self) -> datetime: + """When the token expires.""" + return self._expiry_time + + @expiry_time.setter + def expiry_time(self, expiry_time: datetime): + if expiry_time is None: + del self.expiry_time + return + if not isinstance(expiry_time, datetime): + raise TypeError('expiry_time must be of type datetime') + self._expiry_time = expiry_time + + @property + def baseUri(self): + return self.base_uri + + @property + def expiryTime(self): + return self.expiry_time + + +ApiCreateDefaultModelProxyTokenRequest._fields = [] + +ApiCreateDefaultModelProxyTokenResponse._fields = [ + FieldMetadata("token", "token", "_token", str, "", PredefinedSerializer()), + FieldMetadata("baseUri", "base_uri", "_base_uri", str, "", PredefinedSerializer()), + FieldMetadata("expiryTime", "expiry_time", "_expiry_time", datetime, None, DateTimeSerializer()), +] +