From ed41a07f68e395d181de661c704019316867caf0 Mon Sep 17 00:00:00 2001 From: Li Ma Date: Wed, 3 Jun 2026 09:17:02 -0700 Subject: [PATCH 1/2] release 0.1.27 --- kagglesdk/__init__.py | 2 +- kagglesdk/benchmarks/types/benchmark_enums.py | 25 +++++++++++++++++ .../types/benchmark_tasks_api_service.py | 28 ++++++++++++++++++- kagglesdk/competitions/types/episode.py | 8 +++--- kagglesdk/discussions/types/writeup_types.py | 22 +++++++++++++++ kagglesdk/kaggle_http_client.py | 12 +++----- .../kernels/types/kernels_api_service.py | 16 +++++++++++ kagglesdk/security/types/security_types.py | 1 + 8 files changed, 100 insertions(+), 14 deletions(-) diff --git a/kagglesdk/__init__.py b/kagglesdk/__init__.py index 2b9a56f..ad11a7c 100644 --- a/kagglesdk/__init__.py +++ b/kagglesdk/__init__.py @@ -1,4 +1,4 @@ -__version__ = "0.1.27" +__version__ = "0.1.28" from kagglesdk.kaggle_client import KaggleClient from kagglesdk.kaggle_creds import KaggleCredentials diff --git a/kagglesdk/benchmarks/types/benchmark_enums.py b/kagglesdk/benchmarks/types/benchmark_enums.py index b68707d..2582c83 100644 --- a/kagglesdk/benchmarks/types/benchmark_enums.py +++ b/kagglesdk/benchmarks/types/benchmark_enums.py @@ -27,6 +27,23 @@ class BenchmarkTaskVersionCreationState(enum.Enum): BENCHMARK_TASK_VERSION_CREATION_STATE_VALIDATION_FAILED = 6 BENCHMARK_TASK_VERSION_CREATION_STATE_NO_MODEL_SPECIFIED = 7 +class BenchmarkTaskVersionSource(enum.Enum): + r""" + Where a BenchmarkTaskVersion was created from. Used for analytics and future + per-source policy hooks; sandbox tasks are listed alongside the existing + manual UNSPECIFIED flow without gating. + """ + BENCHMARK_TASK_VERSION_SOURCE_UNSPECIFIED = 0 + EVAL_SANDBOX = 1 + """Created by the LIH 'Benchmark Sandbox: Discover What Works' flow.""" + WEB = 2 + r""" + Created via the kaggle.com web client (e.g. CreateBenchmarkTaskFromPrompt + or saving a benchmark task from a kernel session). + """ + CLI = 3 + """Created via the Kaggle CLI / public BenchmarkTasksApi handler.""" + class Modality(enum.Enum): """Modality types supported by a benchmark model version.""" MODALITY_UNSPECIFIED = 0 @@ -41,4 +58,12 @@ class BenchmarkTaskRunState(enum.Enum): BENCHMARK_TASK_RUN_STATE_RUNNING = 2 BENCHMARK_TASK_RUN_STATE_COMPLETED = 3 BENCHMARK_TASK_RUN_STATE_ERRORED = 4 + BENCHMARK_TASK_RUN_STATE_SCORE_PENDING = 5 + r""" + Indicates that scoring for the run is still pending. + + For the initial implementation of CompsBench infra (go/compsbench-infra). + The session has completed running, but we're still awaiting a + score from the competitions scoring system. + """ diff --git a/kagglesdk/benchmarks/types/benchmark_tasks_api_service.py b/kagglesdk/benchmarks/types/benchmark_tasks_api_service.py index 3be7612..886dd01 100644 --- a/kagglesdk/benchmarks/types/benchmark_tasks_api_service.py +++ b/kagglesdk/benchmarks/types/benchmark_tasks_api_service.py @@ -1,5 +1,5 @@ from datetime import datetime -from kagglesdk.benchmarks.types.benchmark_enums import BenchmarkTaskRunState, BenchmarkTaskVersionCreationState +from kagglesdk.benchmarks.types.benchmark_enums import BenchmarkTaskRunState, BenchmarkTaskVersionCreationState, BenchmarkTaskVersionSource from kagglesdk.benchmarks.types.benchmark_task_run_service import BatchScheduleBenchmarkModelVersionResult from kagglesdk.benchmarks.types.benchmark_types import BenchmarkTaskOptions from kagglesdk.kaggle_object import * @@ -124,6 +124,11 @@ class ApiBenchmarkTask(KaggleObject): from CreateBenchmarkTask so callers can see what was attached, and returned on reads so the CLI can display the currently-attached sources. De-duplicated relative to the request input. + source (BenchmarkTaskVersionSource) + How this task version was produced (sandbox publish, CLI, notebook + editor, etc.). Mirrors BenchmarkTaskVersion.source from the internal + proto; carried through so API consumers can label sandbox-origin + tasks distinctly from manually authored ones. """ def __init__(self): @@ -137,6 +142,7 @@ def __init__(self): self._source_kernel_id = None self._is_backing_notebook_published = None self._options = None + self._source = BenchmarkTaskVersionSource.BENCHMARK_TASK_VERSION_SOURCE_UNSPECIFIED self._freeze() @property @@ -290,6 +296,25 @@ def options(self, options: Optional[Optional['BenchmarkTaskOptions']]): raise TypeError('options must be of type BenchmarkTaskOptions') self._options = options + @property + def source(self) -> 'BenchmarkTaskVersionSource': + r""" + How this task version was produced (sandbox publish, CLI, notebook + editor, etc.). Mirrors BenchmarkTaskVersion.source from the internal + proto; carried through so API consumers can label sandbox-origin + tasks distinctly from manually authored ones. + """ + return self._source + + @source.setter + def source(self, source: 'BenchmarkTaskVersionSource'): + if source is None: + del self.source + return + if not isinstance(source, BenchmarkTaskVersionSource): + raise TypeError('source must be of type BenchmarkTaskVersionSource') + self._source = source + class ApiBenchmarkTaskRun(KaggleObject): r""" @@ -1178,6 +1203,7 @@ def body_fields(): FieldMetadata("sourceKernelId", "source_kernel_id", "_source_kernel_id", int, None, PredefinedSerializer(), optional=True), FieldMetadata("isBackingNotebookPublished", "is_backing_notebook_published", "_is_backing_notebook_published", bool, None, PredefinedSerializer(), optional=True), FieldMetadata("options", "options", "_options", BenchmarkTaskOptions, None, KaggleObjectSerializer(), optional=True), + FieldMetadata("source", "source", "_source", BenchmarkTaskVersionSource, BenchmarkTaskVersionSource.BENCHMARK_TASK_VERSION_SOURCE_UNSPECIFIED, EnumSerializer()), ] ApiBenchmarkTaskRun._fields = [ diff --git a/kagglesdk/competitions/types/episode.py b/kagglesdk/competitions/types/episode.py index 18a7261..c3f3d92 100644 --- a/kagglesdk/competitions/types/episode.py +++ b/kagglesdk/competitions/types/episode.py @@ -30,10 +30,10 @@ class EpisodeType(enum.Enum): """This is deprecated / was never supported.""" EPISODE_TYPE_EXHIBITION = 3 r""" - Used exclusively for 'canary' episodes generated by GenerateEpisodesScheduledHandler - for Game Arena leaderboard competitions. These episodes do not affect leaderboard - scores and are used to validate agent behavior and provide coverage across - eligible submissions. + Used exclusively for 'canary' episodes generated by + GenerateEpisodesScheduledHandler for Game Arena leaderboard competitions. + These episodes do not affect leaderboard scores and are used to validate + agent behavior and provide coverage across eligible submissions. """ EPISODE_TYPE_VALIDATION = 4 diff --git a/kagglesdk/discussions/types/writeup_types.py b/kagglesdk/discussions/types/writeup_types.py index 1566eda..7d2ca74 100644 --- a/kagglesdk/discussions/types/writeup_types.py +++ b/kagglesdk/discussions/types/writeup_types.py @@ -301,6 +301,9 @@ class WriteUp(KaggleObject): saved_thumbnail_image_url (str) Raw (un-fallback'd) saved thumbnail image URL from the DB. See `saved_cover_image_url` for rationale. + doi (str) + A DataCite DOI reference identifier, if available. + e.g. '12.34567/KAGGLE/W/1234567' """ def __init__(self): @@ -331,6 +334,7 @@ def __init__(self): self._publish_time = None self._saved_cover_image_url = "" self._saved_thumbnail_image_url = "" + self._doi = None self._freeze() @property @@ -731,6 +735,23 @@ def saved_thumbnail_image_url(self, saved_thumbnail_image_url: str): raise TypeError('saved_thumbnail_image_url must be of type str') self._saved_thumbnail_image_url = saved_thumbnail_image_url + @property + def doi(self) -> str: + r""" + A DataCite DOI reference identifier, if available. + e.g. '12.34567/KAGGLE/W/1234567' + """ + return self._doi or "" + + @doi.setter + def doi(self, doi: Optional[str]): + if doi is None: + del self.doi + return + if not isinstance(doi, str): + raise TypeError('doi must be of type str') + self._doi = doi + class WriteUpImageInfo(KaggleObject): r""" @@ -1377,6 +1398,7 @@ def is_phone_verified(self, is_phone_verified: Optional[bool]): FieldMetadata("publishTime", "publish_time", "_publish_time", datetime, None, DateTimeSerializer()), FieldMetadata("savedCoverImageUrl", "saved_cover_image_url", "_saved_cover_image_url", str, "", PredefinedSerializer()), FieldMetadata("savedThumbnailImageUrl", "saved_thumbnail_image_url", "_saved_thumbnail_image_url", str, "", PredefinedSerializer()), + FieldMetadata("doi", "doi", "_doi", str, None, PredefinedSerializer(), optional=True), ] WriteUpImageInfo._fields = [ diff --git a/kagglesdk/kaggle_http_client.py b/kagglesdk/kaggle_http_client.py index 6d4ae7d..da33bfe 100644 --- a/kagglesdk/kaggle_http_client.py +++ b/kagglesdk/kaggle_http_client.py @@ -42,14 +42,10 @@ def _get_apikey_creds(): if not kaggle_json or not kaggle_json.strip(): return None - try: - "Be careful, since the file may be used for more than credential storage." - api_key_data = json.loads(kaggle_json) - username = api_key_data["username"] - api_key = api_key_data["key"] - return username, api_key - except KeyError as e: - return None + api_key_data = json.loads(kaggle_json) + username = api_key_data["username"] + api_key = api_key_data["key"] + return username, api_key class KaggleHttpClient(object): diff --git a/kagglesdk/kernels/types/kernels_api_service.py b/kagglesdk/kernels/types/kernels_api_service.py index c584c4b..f7bf268 100644 --- a/kagglesdk/kernels/types/kernels_api_service.py +++ b/kagglesdk/kernels/types/kernels_api_service.py @@ -591,11 +591,13 @@ class ApiGetKernelRequest(KaggleObject): Attributes: user_name (str) kernel_slug (str) + version_number (int) """ def __init__(self): self._user_name = "" self._kernel_slug = "" + self._version_number = None self._freeze() @property @@ -624,6 +626,19 @@ def kernel_slug(self, kernel_slug: str): raise TypeError('kernel_slug must be of type str') self._kernel_slug = kernel_slug + @property + def version_number(self) -> int: + return self._version_number or 0 + + @version_number.setter + def version_number(self, version_number: Optional[int]): + if version_number is None: + del self.version_number + return + if not isinstance(version_number, int): + raise TypeError('version_number must be of type int') + self._version_number = version_number + def endpoint(self): path = '/api/v1/kernels/pull' return path.format_map(self.to_field_map(self)) @@ -2572,6 +2587,7 @@ def kernelId(self): ApiGetKernelRequest._fields = [ FieldMetadata("userName", "user_name", "_user_name", str, "", PredefinedSerializer()), FieldMetadata("kernelSlug", "kernel_slug", "_kernel_slug", str, "", PredefinedSerializer()), + FieldMetadata("versionNumber", "version_number", "_version_number", int, None, PredefinedSerializer(), optional=True), ] ApiGetKernelResponse._fields = [ diff --git a/kagglesdk/security/types/security_types.py b/kagglesdk/security/types/security_types.py index a1574dd..a883b5c 100644 --- a/kagglesdk/security/types/security_types.py +++ b/kagglesdk/security/types/security_types.py @@ -68,6 +68,7 @@ class KaggleResourceType(enum.Enum): KAGGLE_RESOURCE_TYPE_TEAM_MERGE_REQUESTS = 322 KAGGLE_RESOURCE_TYPE_HACKATHON_WRITE_UPS = 324 KAGGLE_RESOURCE_TYPE_COMPETITION_METRIC_VERSIONS = 326 + KAGGLE_RESOURCE_TYPE_HACKATHONS = 328 KAGGLE_RESOURCE_TYPE_DATASETS = 400 """---------- Datasets ----------""" KAGGLE_RESOURCE_TYPE_DATASET_VERSIONS = 404 From dfd64201f12d3fe676b04b199a2c490bf22c83c6 Mon Sep 17 00:00:00 2001 From: Li Ma Date: Wed, 3 Jun 2026 09:23:08 -0700 Subject: [PATCH 2/2] restore get_web_endpoint --- kagglesdk/kaggle_env.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/kagglesdk/kaggle_env.py b/kagglesdk/kaggle_env.py index d2e944f..d378388 100644 --- a/kagglesdk/kaggle_env.py +++ b/kagglesdk/kaggle_env.py @@ -35,6 +35,13 @@ def get_endpoint(env: KaggleEnv): return _env_to_endpoint[env] +def get_web_endpoint(env: KaggleEnv): + # In PROD, the `api` subdomain is used which breaks link to detail pages. + if env == KaggleEnv.PROD: + return "https://kaggle.com" + return get_endpoint(env) + + def get_env(): env = os.getenv("KAGGLE_API_ENVIRONMENT") if env is None or env == "PROD":