From e721a4276c43805e5afcf1b125f1fe4f61ee18af Mon Sep 17 00:00:00 2001 From: Bovard Doerschuk-Tiberi Date: Tue, 11 Aug 2026 03:28:02 +0000 Subject: [PATCH] Regenerate SDK and release 0.1.38 Regenerated with `kapigen --public-api-output-path` (per README) from kaggleazure ci at 7cffc84d6f5. Changes surfaced by the regen: - Add `update_benchmark_task` and `update_benchmark_task_version` to `BenchmarkTasksApiClient`, with `ApiUpdateBenchmarkTaskRequest`/`Response`, `ApiUpdateBenchmarkTaskVersionRequest`, and a new `ApiBenchmarkTaskCitation` type. - Add `add_tasks_to_benchmark` to `BenchmarksApiClient`, with `ApiAddTasksToBenchmarkRequest`/`Response`. - Add the `BenchmarkCandidateType` enum (model versions vs. agents) and `agent_id`/`candidate_type` to `BatchScheduleBenchmarkModelVersionResult`, plus doc updates renaming the batch-schedule request fields to `benchmark_*_ids`. - Add `private_leaderboard_release_date` to `CompetitionSettings`. - Add `resource_filter_scope_id` to `GenerateAccessTokenRequest`. - Add `KAGGLE_RESOURCE_TYPE_RESOURCE_FILTER_SCOPES` to `security_types`. The diff is purely additive: no files added or removed, and no existing fields or methods dropped. --- kagglesdk/__init__.py | 2 +- .../services/benchmark_tasks_api_service.py | 34 +- .../services/benchmarks_api_service.py | 34 +- kagglesdk/benchmarks/types/benchmark_enums.py | 9 + .../types/benchmark_task_run_service.py | 65 ++- .../types/benchmark_tasks_api_service.py | 531 ++++++++++++++++++ .../types/benchmarks_api_service.py | 163 +++++- kagglesdk/competitions/types/host_service.py | 22 + kagglesdk/security/types/security_types.py | 1 + kagglesdk/users/types/account_service.py | 42 ++ 10 files changed, 887 insertions(+), 16 deletions(-) diff --git a/kagglesdk/__init__.py b/kagglesdk/__init__.py index 252ffd9..1a487f5 100644 --- a/kagglesdk/__init__.py +++ b/kagglesdk/__init__.py @@ -1,4 +1,4 @@ -__version__ = "0.1.37" +__version__ = "0.1.38" from kagglesdk.kaggle_client import KaggleClient from kagglesdk.kaggle_creds import KaggleCredentials diff --git a/kagglesdk/benchmarks/services/benchmark_tasks_api_service.py b/kagglesdk/benchmarks/services/benchmark_tasks_api_service.py index dc0125f..33ed5e8 100644 --- a/kagglesdk/benchmarks/services/benchmark_tasks_api_service.py +++ b/kagglesdk/benchmarks/services/benchmark_tasks_api_service.py @@ -1,4 +1,4 @@ -from kagglesdk.benchmarks.types.benchmark_tasks_api_service import ApiBatchScheduleBenchmarkTaskRunsRequest, ApiBatchScheduleBenchmarkTaskRunsResponse, ApiBenchmarkTask, ApiCreateBenchmarkTaskRequest, ApiDownloadBenchmarkTaskRunOutputRequest, ApiGetBenchmarkTaskQuotaRequest, ApiGetBenchmarkTaskQuotaResponse, ApiGetBenchmarkTaskRequest, ApiGetBenchmarkTaskRunLogsRequest, ApiListBenchmarkTaskRunsRequest, ApiListBenchmarkTaskRunsResponse, ApiListBenchmarkTasksRequest, ApiListBenchmarkTasksResponse, ApiPublishBenchmarkTaskRequest +from kagglesdk.benchmarks.types.benchmark_tasks_api_service import ApiBatchScheduleBenchmarkTaskRunsRequest, ApiBatchScheduleBenchmarkTaskRunsResponse, ApiBenchmarkTask, ApiCreateBenchmarkTaskRequest, ApiDownloadBenchmarkTaskRunOutputRequest, ApiGetBenchmarkTaskQuotaRequest, ApiGetBenchmarkTaskQuotaResponse, ApiGetBenchmarkTaskRequest, ApiGetBenchmarkTaskRunLogsRequest, ApiListBenchmarkTaskRunsRequest, ApiListBenchmarkTaskRunsResponse, ApiListBenchmarkTasksRequest, ApiListBenchmarkTasksResponse, ApiPublishBenchmarkTaskRequest, ApiUpdateBenchmarkTaskRequest, ApiUpdateBenchmarkTaskResponse, ApiUpdateBenchmarkTaskVersionRequest from kagglesdk.common.types.file_download import FileDownload from kagglesdk.kaggle_http_client import KaggleHttpClient @@ -141,3 +141,35 @@ def publish_benchmark_task(self, request: ApiPublishBenchmarkTaskRequest = None) request = ApiPublishBenchmarkTaskRequest() return self._client.call("benchmarks.BenchmarkTasksApiService", "PublishBenchmarkTask", request, ApiBenchmarkTask) + + def update_benchmark_task(self, request: ApiUpdateBenchmarkTaskRequest = None) -> ApiUpdateBenchmarkTaskResponse: + r""" + Update editable metadata (description, tags, provenance, citations) on a + task. Only the fields named in `update_mask` are written. Everything but + `tags` is written to the task's *current* version; to target an older + version, use UpdateBenchmarkTaskVersion. + + Args: + request (ApiUpdateBenchmarkTaskRequest): + The request object; initialized to empty instance if not specified. + """ + + if request is None: + request = ApiUpdateBenchmarkTaskRequest() + + return self._client.call("benchmarks.BenchmarkTasksApiService", "UpdateBenchmarkTask", request, ApiUpdateBenchmarkTaskResponse) + + def update_benchmark_task_version(self, request: ApiUpdateBenchmarkTaskVersionRequest = None) -> ApiBenchmarkTask: + r""" + Update editable metadata on one specific version of a task. Unlike + UpdateBenchmarkTask, the version named by the slug is the version written. + + Args: + request (ApiUpdateBenchmarkTaskVersionRequest): + The request object; initialized to empty instance if not specified. + """ + + if request is None: + request = ApiUpdateBenchmarkTaskVersionRequest() + + return self._client.call("benchmarks.BenchmarkTasksApiService", "UpdateBenchmarkTaskVersion", request, ApiBenchmarkTask) diff --git a/kagglesdk/benchmarks/services/benchmarks_api_service.py b/kagglesdk/benchmarks/services/benchmarks_api_service.py index 970ddc4..438512c 100644 --- a/kagglesdk/benchmarks/services/benchmarks_api_service.py +++ b/kagglesdk/benchmarks/services/benchmarks_api_service.py @@ -1,4 +1,4 @@ -from kagglesdk.benchmarks.types.benchmarks_api_service import ApiBenchmarkLeaderboard, ApiBenchmarkModelVersionConfig, ApiCreateBenchmarkModelVersionConfigRequest, ApiCreateBenchmarkVersionAgentMappingsRequest, ApiCreateBenchmarkVersionAgentMappingsResponse, ApiDeleteBenchmarkVersionAgentMappingsRequest, ApiDeleteBenchmarkVersionAgentMappingsResponse, ApiGetBenchmarkLeaderboardRequest, ApiGetBenchmarkModelVersionConfigRequest, ApiListBenchmarkModelsRequest, ApiListBenchmarkModelsResponse, ApiListBenchmarkModelVersionConfigsRequest, ApiListBenchmarkModelVersionConfigsResponse, ApiListBenchmarkVersionAgentMappingsRequest, ApiListBenchmarkVersionAgentMappingsResponse +from kagglesdk.benchmarks.types.benchmarks_api_service import ApiAddTasksToBenchmarkRequest, ApiAddTasksToBenchmarkResponse, ApiBenchmarkLeaderboard, ApiBenchmarkModelVersionConfig, ApiCreateBenchmarkModelVersionConfigRequest, ApiCreateBenchmarkVersionAgentMappingsRequest, ApiCreateBenchmarkVersionAgentMappingsResponse, ApiDeleteBenchmarkVersionAgentMappingsRequest, ApiDeleteBenchmarkVersionAgentMappingsResponse, ApiGetBenchmarkLeaderboardRequest, ApiGetBenchmarkModelVersionConfigRequest, ApiListBenchmarkModelsRequest, ApiListBenchmarkModelsResponse, ApiListBenchmarkModelVersionConfigsRequest, ApiListBenchmarkModelVersionConfigsResponse, ApiListBenchmarkVersionAgentMappingsRequest, ApiListBenchmarkVersionAgentMappingsResponse from kagglesdk.kaggle_http_client import KaggleHttpClient class BenchmarksApiClient(object): @@ -184,3 +184,35 @@ def list_benchmark_version_agent_mappings(self, request: ApiListBenchmarkVersion request = ApiListBenchmarkVersionAgentMappingsRequest() return self._client.call("benchmarks.BenchmarksApiService", "ListBenchmarkVersionAgentMappings", request, ApiListBenchmarkVersionAgentMappingsResponse) + + def add_tasks_to_benchmark(self, request: ApiAddTasksToBenchmarkRequest = None) -> ApiAddTasksToBenchmarkResponse: + r""" + Map one or more BenchmarkTasks into one of the current user's own + benchmarks, making them part of that benchmark's task tree and + leaderboard. Only supported for benchmarks of type Personal. Requires + update access to the benchmark version and read access to each task. Tasks + already mapped to the benchmark are skipped and echoed back in + `skipped_tasks` rather than failing the request, so a partially-applied + bulk import can be safely re-run. + + Example: + curl -sSL -u fickleone:local_api_token \ + -X POST \ + http://localhost/api/v1/benchmarks/my-benchmark/tasks/add \ + -H 'Content-Type: application/json' \ + -d '{ + 'taskSlugs': [ + {'taskSlug': 'count-letters'}, + {'ownerSlug': 'bob', 'taskSlug': 'sort-list', 'versionNumber': 2} + ] + }' + + Args: + request (ApiAddTasksToBenchmarkRequest): + The request object; initialized to empty instance if not specified. + """ + + if request is None: + request = ApiAddTasksToBenchmarkRequest() + + return self._client.call("benchmarks.BenchmarksApiService", "AddTasksToBenchmark", request, ApiAddTasksToBenchmarkResponse) diff --git a/kagglesdk/benchmarks/types/benchmark_enums.py b/kagglesdk/benchmarks/types/benchmark_enums.py index 9721ca8..f6edd16 100644 --- a/kagglesdk/benchmarks/types/benchmark_enums.py +++ b/kagglesdk/benchmarks/types/benchmark_enums.py @@ -1,5 +1,14 @@ import enum +class BenchmarkCandidateType(enum.Enum): + r""" + Saved to the DB. Do not modify existing values. + The kind of candidate a BenchmarkTaskVersion evaluates. + """ + BENCHMARK_CANDIDATE_TYPE_UNSPECIFIED = 0 + BENCHMARK_CANDIDATE_TYPE_MODEL_VERSIONS = 1 + BENCHMARK_CANDIDATE_TYPE_AGENTS = 2 + class BenchmarkModelImportanceLevel(enum.Enum): r""" Determines whether the model will be run on diff --git a/kagglesdk/benchmarks/types/benchmark_task_run_service.py b/kagglesdk/benchmarks/types/benchmark_task_run_service.py index 652cb94..49cebc9 100644 --- a/kagglesdk/benchmarks/types/benchmark_task_run_service.py +++ b/kagglesdk/benchmarks/types/benchmark_task_run_service.py @@ -1,3 +1,4 @@ +from kagglesdk.benchmarks.types.benchmark_enums import BenchmarkCandidateType from kagglesdk.kaggle_object import * from typing import Optional @@ -6,20 +7,25 @@ class BatchScheduleBenchmarkModelVersionResult(KaggleObject): Attributes: benchmark_model_version_id (int) One of the values provided in - BatchScheduleBenchmarkTaskRunsRequest.benchmark_model_versions + BatchScheduleBenchmarkTaskRunsRequest.benchmark_model_version_ids run_scheduled (bool) - Whether the run was scheduled for the provided (benchmark_task_version, - benchmark_model_version) pair + Whether the run was scheduled for the provided (TaskVersion, Candidate) + pair. run_skipped_reason (str) - If run_scheduled was false, the reason the provided - (benchmark_task_version, benchmark_model_version) pair was skipped + If run_scheduled was false, the reason the (TaskVersion, Candidate) pair + was skipped benchmark_task_version_id (int) One of the values provided in - BatchScheduleBenchmarkTaskRunsRequest.benchmark_task_versions + BatchScheduleBenchmarkTaskRunsRequest.benchmark_task_version_ids parent_task_version_id (int) When the requested benchmark_task_version_id is a child of another task version, scheduling is redirected to the parent and this field reports the parent's id. Unset when the requested task version was executed directly. + agent_id (int) + One of the values provided in + BatchScheduleBenchmarkTaskRunsRequest.benchmark_agent_ids + candidate_type (BenchmarkCandidateType) + Specifies the candidate type that was scheduled (ModelVersion vs. Agent) """ def __init__(self): @@ -28,13 +34,15 @@ def __init__(self): self._run_skipped_reason = None self._benchmark_task_version_id = 0 self._parent_task_version_id = None + self._agent_id = 0 + self._candidate_type = BenchmarkCandidateType.BENCHMARK_CANDIDATE_TYPE_UNSPECIFIED self._freeze() @property def benchmark_task_version_id(self) -> int: r""" One of the values provided in - BatchScheduleBenchmarkTaskRunsRequest.benchmark_task_versions + BatchScheduleBenchmarkTaskRunsRequest.benchmark_task_version_ids """ return self._benchmark_task_version_id @@ -51,7 +59,7 @@ def benchmark_task_version_id(self, benchmark_task_version_id: int): def benchmark_model_version_id(self) -> int: r""" One of the values provided in - BatchScheduleBenchmarkTaskRunsRequest.benchmark_model_versions + BatchScheduleBenchmarkTaskRunsRequest.benchmark_model_version_ids """ return self._benchmark_model_version_id @@ -64,11 +72,42 @@ def benchmark_model_version_id(self, benchmark_model_version_id: int): raise TypeError('benchmark_model_version_id must be of type int') self._benchmark_model_version_id = benchmark_model_version_id + @property + def agent_id(self) -> int: + r""" + One of the values provided in + BatchScheduleBenchmarkTaskRunsRequest.benchmark_agent_ids + """ + return self._agent_id + + @agent_id.setter + def agent_id(self, agent_id: int): + if agent_id is None: + del self.agent_id + return + if not isinstance(agent_id, int): + raise TypeError('agent_id must be of type int') + self._agent_id = agent_id + + @property + def candidate_type(self) -> 'BenchmarkCandidateType': + """Specifies the candidate type that was scheduled (ModelVersion vs. Agent)""" + return self._candidate_type + + @candidate_type.setter + def candidate_type(self, candidate_type: 'BenchmarkCandidateType'): + if candidate_type is None: + del self.candidate_type + return + if not isinstance(candidate_type, BenchmarkCandidateType): + raise TypeError('candidate_type must be of type BenchmarkCandidateType') + self._candidate_type = candidate_type + @property def run_scheduled(self) -> bool: r""" - Whether the run was scheduled for the provided (benchmark_task_version, - benchmark_model_version) pair + Whether the run was scheduled for the provided (TaskVersion, Candidate) + pair. """ return self._run_scheduled @@ -84,8 +123,8 @@ def run_scheduled(self, run_scheduled: bool): @property def run_skipped_reason(self) -> str: r""" - If run_scheduled was false, the reason the provided - (benchmark_task_version, benchmark_model_version) pair was skipped + If run_scheduled was false, the reason the (TaskVersion, Candidate) pair + was skipped """ return self._run_skipped_reason or "" @@ -123,5 +162,7 @@ def parent_task_version_id(self, parent_task_version_id: Optional[int]): FieldMetadata("runSkippedReason", "run_skipped_reason", "_run_skipped_reason", str, None, PredefinedSerializer(), optional=True), FieldMetadata("benchmarkTaskVersionId", "benchmark_task_version_id", "_benchmark_task_version_id", int, 0, PredefinedSerializer()), FieldMetadata("parentTaskVersionId", "parent_task_version_id", "_parent_task_version_id", int, None, PredefinedSerializer(), optional=True), + FieldMetadata("agentId", "agent_id", "_agent_id", int, 0, PredefinedSerializer()), + FieldMetadata("candidateType", "candidate_type", "_candidate_type", BenchmarkCandidateType, BenchmarkCandidateType.BENCHMARK_CANDIDATE_TYPE_UNSPECIFIED, EnumSerializer()), ] diff --git a/kagglesdk/benchmarks/types/benchmark_tasks_api_service.py b/kagglesdk/benchmarks/types/benchmark_tasks_api_service.py index 8ff64fa..85eb27b 100644 --- a/kagglesdk/benchmarks/types/benchmark_tasks_api_service.py +++ b/kagglesdk/benchmarks/types/benchmark_tasks_api_service.py @@ -1,4 +1,5 @@ from datetime import datetime +from google.protobuf.field_mask_pb2 import FieldMask 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 BenchmarkTaskKaggleDatasetsDefinition, BenchmarkTaskOptions, EnvVariable, UserSecret @@ -12,11 +13,16 @@ class ApiBatchScheduleBenchmarkTaskRunsRequest(KaggleObject): model_version_slugs (str) Canonical BenchmarkModelVersion.Slug values (e.g. 'claude-sonnet-4-6-default'). + agent_slugs (str) + Canonical Agent.Slug values (e.g. + 'claude-code-2.1.216-opus-4.8-high'). Agents are backed by model versions + and follow the same validation checks. """ def __init__(self): self._task_slugs = [] self._model_version_slugs = [] + self._agent_slugs = [] self._freeze() @property @@ -53,6 +59,26 @@ def model_version_slugs(self, model_version_slugs: Optional[List[str]]): raise TypeError('model_version_slugs must contain only items of type str') self._model_version_slugs = model_version_slugs + @property + def agent_slugs(self) -> Optional[List[str]]: + r""" + Canonical Agent.Slug values (e.g. + 'claude-code-2.1.216-opus-4.8-high'). Agents are backed by model versions + and follow the same validation checks. + """ + return self._agent_slugs + + @agent_slugs.setter + def agent_slugs(self, agent_slugs: Optional[List[str]]): + if agent_slugs is None: + del self.agent_slugs + return + if not isinstance(agent_slugs, list): + raise TypeError('agent_slugs must be of type list') + if not all([isinstance(t, str) for t in agent_slugs]): + raise TypeError('agent_slugs must contain only items of type str') + self._agent_slugs = agent_slugs + def endpoint(self): path = '/api/v1/benchmarks/tasks/schedule' return path.format_map(self.to_field_map(self)) @@ -129,6 +155,16 @@ class ApiBenchmarkTask(KaggleObject): editor, etc.). Mirrors BenchmarkTaskVersion.source from the internal proto; carried through so API consumers can label sandbox-origin tasks distinctly from manually authored ones. + description (str) + Markdown details shown on the task page, from the task's current version. + tags (str) + Tag names on the task, in their canonical stored form (lowercase). + provenance_sources (str) + Free-text provenance for the data/code behind the task, from the task's + current version. Stored as at most 4000 characters after sanitization; + longer values are rejected with InvalidArgument on update. + citations (ApiBenchmarkTaskCitation) + Citations on the task's current version. """ def __init__(self): @@ -143,6 +179,10 @@ def __init__(self): self._is_backing_notebook_published = None self._options = None self._source = BenchmarkTaskVersionSource.BENCHMARK_TASK_VERSION_SOURCE_UNSPECIFIED + self._description = None + self._tags = [] + self._provenance_sources = None + self._citations = [] self._freeze() @property @@ -315,6 +355,119 @@ def source(self, source: 'BenchmarkTaskVersionSource'): raise TypeError('source must be of type BenchmarkTaskVersionSource') self._source = source + @property + def description(self) -> str: + """Markdown details shown on the task page, from the task's current version.""" + return self._description or "" + + @description.setter + def description(self, description: Optional[str]): + if description is None: + del self.description + return + if not isinstance(description, str): + raise TypeError('description must be of type str') + self._description = description + + @property + def tags(self) -> Optional[List[str]]: + """Tag names on the task, in their canonical stored form (lowercase).""" + return self._tags + + @tags.setter + def tags(self, tags: Optional[List[str]]): + if tags is None: + del self.tags + return + if not isinstance(tags, list): + raise TypeError('tags must be of type list') + if not all([isinstance(t, str) for t in tags]): + raise TypeError('tags must contain only items of type str') + self._tags = tags + + @property + def provenance_sources(self) -> str: + r""" + Free-text provenance for the data/code behind the task, from the task's + current version. Stored as at most 4000 characters after sanitization; + longer values are rejected with InvalidArgument on update. + """ + return self._provenance_sources or "" + + @provenance_sources.setter + def provenance_sources(self, provenance_sources: Optional[str]): + if provenance_sources is None: + del self.provenance_sources + return + if not isinstance(provenance_sources, str): + raise TypeError('provenance_sources must be of type str') + self._provenance_sources = provenance_sources + + @property + def citations(self) -> Optional[List[Optional['ApiBenchmarkTaskCitation']]]: + """Citations on the task's current version.""" + return self._citations + + @citations.setter + def citations(self, citations: Optional[List[Optional['ApiBenchmarkTaskCitation']]]): + if citations is None: + del self.citations + return + if not isinstance(citations, list): + raise TypeError('citations must be of type list') + if not all([isinstance(t, ApiBenchmarkTaskCitation) for t in citations]): + raise TypeError('citations must contain only items of type ApiBenchmarkTaskCitation') + self._citations = citations + + +class ApiBenchmarkTaskCitation(KaggleObject): + r""" + A reference supporting the data or code behind a benchmark task. + + Attributes: + title (str) + Display text for the reference. Free-form; not validated. + url (str) + Link to the reference, normalized to an absolute http(s) URL. A value with + no scheme is stored as http://, so this may differ from what was sent. + """ + + def __init__(self): + self._title = "" + self._url = "" + self._freeze() + + @property + def title(self) -> str: + """Display text for the reference. Free-form; not validated.""" + return self._title + + @title.setter + def title(self, title: str): + if title is None: + del self.title + return + if not isinstance(title, str): + raise TypeError('title must be of type str') + self._title = title + + @property + def url(self) -> str: + r""" + Link to the reference, normalized to an absolute http(s) URL. A value with + no scheme is stored as http://, so this may differ from what was sent. + """ + return self._url + + @url.setter + def url(self, url: str): + if url is None: + del self.url + return + if not isinstance(url, str): + raise TypeError('url must be of type str') + self._url = url + class ApiBenchmarkTaskRun(KaggleObject): r""" @@ -1206,6 +1359,352 @@ def body_fields(): return '*' +class ApiUpdateBenchmarkTaskRequest(KaggleObject): + r""" + Attributes: + slug (ApiBenchmarkTaskSlug) + The task to update. `owner_slug` is optional and defaults to the + authenticated user. `version_number` is rejected here: the fields below + always write the task's current version. Use UpdateBenchmarkTaskVersion to + target a specific version. + description (str) + Markdown details shown on the task page. HTML is sanitized before storage, + so the value read back may differ from what was sent. + tags (str) + Human-readable tag names (e.g. 'computer vision'). Replaces the task's + current tags. Matching is case-insensitive and ignores surrounding + whitespace; names are echoed back in their canonical stored form, which + may differ in case from what was sent. Names that don't match a known tag + are skipped and returned in `invalid_tags`. + provenance_sources (str) + Free-text provenance for the data/code behind the task. Values longer than + 4000 characters after sanitization are rejected with InvalidArgument. + citations (ApiBenchmarkTaskCitation) + Replaces the full citation list for the current version. A citation whose + `url` can't be parsed as an http(s) URL is dropped rather than failing the + request; the rest are still applied. + update_mask (FieldMask) + Which of the above to write. Only fields named here are read. + """ + + def __init__(self): + self._slug = None + self._description = None + self._tags = [] + self._provenance_sources = None + self._citations = [] + self._update_mask = None + self._freeze() + + @property + def slug(self) -> Optional['ApiBenchmarkTaskSlug']: + r""" + The task to update. `owner_slug` is optional and defaults to the + authenticated user. `version_number` is rejected here: the fields below + always write the task's current version. Use UpdateBenchmarkTaskVersion to + target a specific version. + """ + return self._slug + + @slug.setter + def slug(self, slug: Optional['ApiBenchmarkTaskSlug']): + if slug is None: + del self.slug + return + if not isinstance(slug, ApiBenchmarkTaskSlug): + raise TypeError('slug must be of type ApiBenchmarkTaskSlug') + self._slug = slug + + @property + def description(self) -> str: + r""" + Markdown details shown on the task page. HTML is sanitized before storage, + so the value read back may differ from what was sent. + """ + return self._description or "" + + @description.setter + def description(self, description: Optional[str]): + if description is None: + del self.description + return + if not isinstance(description, str): + raise TypeError('description must be of type str') + self._description = description + + @property + def tags(self) -> Optional[List[str]]: + r""" + Human-readable tag names (e.g. 'computer vision'). Replaces the task's + current tags. Matching is case-insensitive and ignores surrounding + whitespace; names are echoed back in their canonical stored form, which + may differ in case from what was sent. Names that don't match a known tag + are skipped and returned in `invalid_tags`. + """ + return self._tags + + @tags.setter + def tags(self, tags: Optional[List[str]]): + if tags is None: + del self.tags + return + if not isinstance(tags, list): + raise TypeError('tags must be of type list') + if not all([isinstance(t, str) for t in tags]): + raise TypeError('tags must contain only items of type str') + self._tags = tags + + @property + def provenance_sources(self) -> str: + r""" + Free-text provenance for the data/code behind the task. Values longer than + 4000 characters after sanitization are rejected with InvalidArgument. + """ + return self._provenance_sources or "" + + @provenance_sources.setter + def provenance_sources(self, provenance_sources: Optional[str]): + if provenance_sources is None: + del self.provenance_sources + return + if not isinstance(provenance_sources, str): + raise TypeError('provenance_sources must be of type str') + self._provenance_sources = provenance_sources + + @property + def citations(self) -> Optional[List[Optional['ApiBenchmarkTaskCitation']]]: + r""" + Replaces the full citation list for the current version. A citation whose + `url` can't be parsed as an http(s) URL is dropped rather than failing the + request; the rest are still applied. + """ + return self._citations + + @citations.setter + def citations(self, citations: Optional[List[Optional['ApiBenchmarkTaskCitation']]]): + if citations is None: + del self.citations + return + if not isinstance(citations, list): + raise TypeError('citations must be of type list') + if not all([isinstance(t, ApiBenchmarkTaskCitation) for t in citations]): + raise TypeError('citations must contain only items of type ApiBenchmarkTaskCitation') + self._citations = citations + + @property + def update_mask(self) -> FieldMask: + """Which of the above to write. Only fields named here are read.""" + return self._update_mask + + @update_mask.setter + def update_mask(self, update_mask: FieldMask): + if update_mask is None: + del self.update_mask + return + if not isinstance(update_mask, FieldMask): + raise TypeError('update_mask must be of type FieldMask') + self._update_mask = update_mask + + def endpoint(self): + path = '/api/v1/benchmarks/tasks/{slug.owner_slug}/{slug.task_slug}/update' + return path.format_map(self.to_field_map(self)) + + + @staticmethod + def method(): + return 'POST' + + @staticmethod + def body_fields(): + return '*' + + +class ApiUpdateBenchmarkTaskResponse(KaggleObject): + r""" + Attributes: + task (ApiBenchmarkTask) + The task as it stands after the update. + invalid_tags (str) + Tag names from the request that didn't match a known tag. These were + skipped; the remaining tags were applied. + """ + + def __init__(self): + self._task = None + self._invalid_tags = [] + self._freeze() + + @property + def task(self) -> Optional['ApiBenchmarkTask']: + """The task as it stands after the update.""" + return self._task + + @task.setter + def task(self, task: Optional['ApiBenchmarkTask']): + if task is None: + del self.task + return + if not isinstance(task, ApiBenchmarkTask): + raise TypeError('task must be of type ApiBenchmarkTask') + self._task = task + + @property + def invalid_tags(self) -> Optional[List[str]]: + r""" + Tag names from the request that didn't match a known tag. These were + skipped; the remaining tags were applied. + """ + return self._invalid_tags + + @invalid_tags.setter + def invalid_tags(self, invalid_tags: Optional[List[str]]): + if invalid_tags is None: + del self.invalid_tags + return + if not isinstance(invalid_tags, list): + raise TypeError('invalid_tags must be of type list') + if not all([isinstance(t, str) for t in invalid_tags]): + raise TypeError('invalid_tags must contain only items of type str') + self._invalid_tags = invalid_tags + + @property + def invalidTags(self): + return self.invalid_tags + + +class ApiUpdateBenchmarkTaskVersionRequest(KaggleObject): + r""" + Attributes: + slug (ApiBenchmarkTaskSlug) + The task version to update. `owner_slug` is optional and defaults to the + authenticated user. `version_number` names the version written, and over + HTTP it is a required path segment. + description (str) + Markdown details shown on the task page. HTML is sanitized before storage, + so the value read back may differ from what was sent. + provenance_sources (str) + Free-text provenance for the data/code behind the task. Values longer than + 4000 characters after sanitization are rejected with InvalidArgument. + citations (ApiBenchmarkTaskCitation) + Replaces the full citation list for this version. A citation whose `url` + can't be parsed as an http(s) URL is dropped rather than failing the + request; the rest are still applied. + update_mask (FieldMask) + Which of the above to write. Only fields named here are read. `tags` is + not writable here: tags are task-scoped, so use UpdateBenchmarkTask. + """ + + def __init__(self): + self._slug = None + self._description = None + self._provenance_sources = None + self._citations = [] + self._update_mask = None + self._freeze() + + @property + def slug(self) -> Optional['ApiBenchmarkTaskSlug']: + r""" + The task version to update. `owner_slug` is optional and defaults to the + authenticated user. `version_number` names the version written, and over + HTTP it is a required path segment. + """ + return self._slug + + @slug.setter + def slug(self, slug: Optional['ApiBenchmarkTaskSlug']): + if slug is None: + del self.slug + return + if not isinstance(slug, ApiBenchmarkTaskSlug): + raise TypeError('slug must be of type ApiBenchmarkTaskSlug') + self._slug = slug + + @property + def description(self) -> str: + r""" + Markdown details shown on the task page. HTML is sanitized before storage, + so the value read back may differ from what was sent. + """ + return self._description or "" + + @description.setter + def description(self, description: Optional[str]): + if description is None: + del self.description + return + if not isinstance(description, str): + raise TypeError('description must be of type str') + self._description = description + + @property + def provenance_sources(self) -> str: + r""" + Free-text provenance for the data/code behind the task. Values longer than + 4000 characters after sanitization are rejected with InvalidArgument. + """ + return self._provenance_sources or "" + + @provenance_sources.setter + def provenance_sources(self, provenance_sources: Optional[str]): + if provenance_sources is None: + del self.provenance_sources + return + if not isinstance(provenance_sources, str): + raise TypeError('provenance_sources must be of type str') + self._provenance_sources = provenance_sources + + @property + def citations(self) -> Optional[List[Optional['ApiBenchmarkTaskCitation']]]: + r""" + Replaces the full citation list for this version. A citation whose `url` + can't be parsed as an http(s) URL is dropped rather than failing the + request; the rest are still applied. + """ + return self._citations + + @citations.setter + def citations(self, citations: Optional[List[Optional['ApiBenchmarkTaskCitation']]]): + if citations is None: + del self.citations + return + if not isinstance(citations, list): + raise TypeError('citations must be of type list') + if not all([isinstance(t, ApiBenchmarkTaskCitation) for t in citations]): + raise TypeError('citations must contain only items of type ApiBenchmarkTaskCitation') + self._citations = citations + + @property + def update_mask(self) -> FieldMask: + r""" + Which of the above to write. Only fields named here are read. `tags` is + not writable here: tags are task-scoped, so use UpdateBenchmarkTask. + """ + return self._update_mask + + @update_mask.setter + def update_mask(self, update_mask: FieldMask): + if update_mask is None: + del self.update_mask + return + if not isinstance(update_mask, FieldMask): + raise TypeError('update_mask must be of type FieldMask') + self._update_mask = update_mask + + def endpoint(self): + path = '/api/v1/benchmarks/tasks/{slug.owner_slug}/{slug.task_slug}/versions/{slug.version_number}/update' + return path.format_map(self.to_field_map(self)) + + + @staticmethod + def method(): + return 'POST' + + @staticmethod + def body_fields(): + return '*' + + class BenchmarkTaskDefinition(KaggleObject): r""" Attributes: @@ -1552,6 +2051,7 @@ class BenchmarkTaskNotebookDefinition(KaggleObject): ApiBatchScheduleBenchmarkTaskRunsRequest._fields = [ FieldMetadata("taskSlugs", "task_slugs", "_task_slugs", ApiBenchmarkTaskSlug, [], ListSerializer(KaggleObjectSerializer())), FieldMetadata("modelVersionSlugs", "model_version_slugs", "_model_version_slugs", str, [], ListSerializer(PredefinedSerializer())), + FieldMetadata("agentSlugs", "agent_slugs", "_agent_slugs", str, [], ListSerializer(PredefinedSerializer())), ] ApiBatchScheduleBenchmarkTaskRunsResponse._fields = [ @@ -1570,6 +2070,15 @@ class BenchmarkTaskNotebookDefinition(KaggleObject): 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()), + FieldMetadata("description", "description", "_description", str, None, PredefinedSerializer(), optional=True), + FieldMetadata("tags", "tags", "_tags", str, [], ListSerializer(PredefinedSerializer())), + FieldMetadata("provenanceSources", "provenance_sources", "_provenance_sources", str, None, PredefinedSerializer(), optional=True), + FieldMetadata("citations", "citations", "_citations", ApiBenchmarkTaskCitation, [], ListSerializer(KaggleObjectSerializer())), +] + +ApiBenchmarkTaskCitation._fields = [ + FieldMetadata("title", "title", "_title", str, "", PredefinedSerializer()), + FieldMetadata("url", "url", "_url", str, "", PredefinedSerializer()), ] ApiBenchmarkTaskRun._fields = [ @@ -1648,6 +2157,28 @@ class BenchmarkTaskNotebookDefinition(KaggleObject): FieldMetadata("publishBackingNotebook", "publish_backing_notebook", "_publish_backing_notebook", bool, False, PredefinedSerializer()), ] +ApiUpdateBenchmarkTaskRequest._fields = [ + FieldMetadata("slug", "slug", "_slug", ApiBenchmarkTaskSlug, None, KaggleObjectSerializer()), + FieldMetadata("description", "description", "_description", str, None, PredefinedSerializer(), optional=True), + FieldMetadata("tags", "tags", "_tags", str, [], ListSerializer(PredefinedSerializer())), + FieldMetadata("provenanceSources", "provenance_sources", "_provenance_sources", str, None, PredefinedSerializer(), optional=True), + FieldMetadata("citations", "citations", "_citations", ApiBenchmarkTaskCitation, [], ListSerializer(KaggleObjectSerializer())), + FieldMetadata("updateMask", "update_mask", "_update_mask", FieldMask, None, FieldMaskSerializer()), +] + +ApiUpdateBenchmarkTaskResponse._fields = [ + FieldMetadata("task", "task", "_task", ApiBenchmarkTask, None, KaggleObjectSerializer()), + FieldMetadata("invalidTags", "invalid_tags", "_invalid_tags", str, [], ListSerializer(PredefinedSerializer())), +] + +ApiUpdateBenchmarkTaskVersionRequest._fields = [ + FieldMetadata("slug", "slug", "_slug", ApiBenchmarkTaskSlug, None, KaggleObjectSerializer()), + FieldMetadata("description", "description", "_description", str, None, PredefinedSerializer(), optional=True), + FieldMetadata("provenanceSources", "provenance_sources", "_provenance_sources", str, None, PredefinedSerializer(), optional=True), + FieldMetadata("citations", "citations", "_citations", ApiBenchmarkTaskCitation, [], ListSerializer(KaggleObjectSerializer())), + FieldMetadata("updateMask", "update_mask", "_update_mask", FieldMask, None, FieldMaskSerializer()), +] + BenchmarkTaskDefinition._fields = [ FieldMetadata("notebook", "notebook", "_notebook", BenchmarkTaskNotebookDefinition, None, KaggleObjectSerializer(), optional=True), FieldMetadata("dockerImage", "docker_image", "_docker_image", BenchmarkTaskDockerImageDefinition, None, KaggleObjectSerializer(), optional=True), diff --git a/kagglesdk/benchmarks/types/benchmarks_api_service.py b/kagglesdk/benchmarks/types/benchmarks_api_service.py index f612879..aac9f11 100644 --- a/kagglesdk/benchmarks/types/benchmarks_api_service.py +++ b/kagglesdk/benchmarks/types/benchmarks_api_service.py @@ -1,9 +1,159 @@ from google.protobuf.field_mask_pb2 import FieldMask from kagglesdk.benchmarks.types.benchmark_enums import BenchmarkVersionAgentMappingType from kagglesdk.benchmarks.types.benchmark_service import ListBenchmarkVersionAgentMappingsFilter +from kagglesdk.benchmarks.types.benchmark_tasks_api_service import ApiBenchmarkTaskSlug from kagglesdk.benchmarks.types.benchmark_types import BenchmarkModel, BenchmarkResult from kagglesdk.kaggle_object import * -from typing import List, Optional +from typing import Optional, List + +class ApiAddTasksToBenchmarkRequest(KaggleObject): + r""" + Attributes: + benchmark_slug (str) + Slug of the benchmark to add to. Always resolved under the current user; + benchmarks owned by anyone else are not addressable here. + version_number (int) + Targets the benchmark's current published version, or its draft when + there is no published version, if omitted. + task_slugs (ApiBenchmarkTaskSlug) + Tasks to map in; must be non-empty. Any task the caller can read may be + mapped, including one owned by another user. Duplicates are collapsed. + """ + + def __init__(self): + self._benchmark_slug = "" + self._version_number = None + self._task_slugs = [] + self._freeze() + + @property + def benchmark_slug(self) -> str: + r""" + Slug of the benchmark to add to. Always resolved under the current user; + benchmarks owned by anyone else are not addressable here. + """ + return self._benchmark_slug + + @benchmark_slug.setter + def benchmark_slug(self, benchmark_slug: str): + if benchmark_slug is None: + del self.benchmark_slug + return + if not isinstance(benchmark_slug, str): + raise TypeError('benchmark_slug must be of type str') + self._benchmark_slug = benchmark_slug + + @property + def version_number(self) -> int: + r""" + Targets the benchmark's current published version, or its draft when + there is no published version, if omitted. + """ + 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 + + @property + def task_slugs(self) -> Optional[List[Optional['ApiBenchmarkTaskSlug']]]: + r""" + Tasks to map in; must be non-empty. Any task the caller can read may be + mapped, including one owned by another user. Duplicates are collapsed. + """ + return self._task_slugs + + @task_slugs.setter + def task_slugs(self, task_slugs: Optional[List[Optional['ApiBenchmarkTaskSlug']]]): + if task_slugs is None: + del self.task_slugs + return + if not isinstance(task_slugs, list): + raise TypeError('task_slugs must be of type list') + if not all([isinstance(t, ApiBenchmarkTaskSlug) for t in task_slugs]): + raise TypeError('task_slugs must contain only items of type ApiBenchmarkTaskSlug') + self._task_slugs = task_slugs + + def endpoint(self): + if self.version_number: + path = '/api/v1/benchmarks/{benchmark_slug}/versions/{version_number}/tasks/add' + else: + path = '/api/v1/benchmarks/{benchmark_slug}/tasks/add' + return path.format_map(self.to_field_map(self)) + + + @staticmethod + def method(): + return 'POST' + + @staticmethod + def body_fields(): + return '*' + + +class ApiAddTasksToBenchmarkResponse(KaggleObject): + r""" + Attributes: + added_tasks (ApiBenchmarkTaskSlug) + Tasks newly mapped by this call, with the resolved owner and version + number filled in. + skipped_tasks (ApiBenchmarkTaskSlug) + Tasks that were already mapped to this benchmark and were left alone. + """ + + def __init__(self): + self._added_tasks = [] + self._skipped_tasks = [] + self._freeze() + + @property + def added_tasks(self) -> Optional[List[Optional['ApiBenchmarkTaskSlug']]]: + r""" + Tasks newly mapped by this call, with the resolved owner and version + number filled in. + """ + return self._added_tasks + + @added_tasks.setter + def added_tasks(self, added_tasks: Optional[List[Optional['ApiBenchmarkTaskSlug']]]): + if added_tasks is None: + del self.added_tasks + return + if not isinstance(added_tasks, list): + raise TypeError('added_tasks must be of type list') + if not all([isinstance(t, ApiBenchmarkTaskSlug) for t in added_tasks]): + raise TypeError('added_tasks must contain only items of type ApiBenchmarkTaskSlug') + self._added_tasks = added_tasks + + @property + def skipped_tasks(self) -> Optional[List[Optional['ApiBenchmarkTaskSlug']]]: + """Tasks that were already mapped to this benchmark and were left alone.""" + return self._skipped_tasks + + @skipped_tasks.setter + def skipped_tasks(self, skipped_tasks: Optional[List[Optional['ApiBenchmarkTaskSlug']]]): + if skipped_tasks is None: + del self.skipped_tasks + return + if not isinstance(skipped_tasks, list): + raise TypeError('skipped_tasks must be of type list') + if not all([isinstance(t, ApiBenchmarkTaskSlug) for t in skipped_tasks]): + raise TypeError('skipped_tasks must contain only items of type ApiBenchmarkTaskSlug') + self._skipped_tasks = skipped_tasks + + @property + def addedTasks(self): + return self.added_tasks + + @property + def skippedTasks(self): + return self.skipped_tasks + class ApiBenchmarkLeaderboard(KaggleObject): r""" @@ -940,6 +1090,17 @@ def nextPageToken(self): return self.next_page_token +ApiAddTasksToBenchmarkRequest._fields = [ + FieldMetadata("benchmarkSlug", "benchmark_slug", "_benchmark_slug", str, "", PredefinedSerializer()), + FieldMetadata("versionNumber", "version_number", "_version_number", int, None, PredefinedSerializer(), optional=True), + FieldMetadata("taskSlugs", "task_slugs", "_task_slugs", ApiBenchmarkTaskSlug, [], ListSerializer(KaggleObjectSerializer())), +] + +ApiAddTasksToBenchmarkResponse._fields = [ + FieldMetadata("addedTasks", "added_tasks", "_added_tasks", ApiBenchmarkTaskSlug, [], ListSerializer(KaggleObjectSerializer())), + FieldMetadata("skippedTasks", "skipped_tasks", "_skipped_tasks", ApiBenchmarkTaskSlug, [], ListSerializer(KaggleObjectSerializer())), +] + ApiBenchmarkLeaderboard.LeaderboardRow._fields = [ FieldMetadata("modelVersionName", "model_version_name", "_model_version_name", str, "", PredefinedSerializer()), FieldMetadata("modelVersionSlug", "model_version_slug", "_model_version_slug", str, "", PredefinedSerializer()), diff --git a/kagglesdk/competitions/types/host_service.py b/kagglesdk/competitions/types/host_service.py index 76ffcdd..6d800a3 100644 --- a/kagglesdk/competitions/types/host_service.py +++ b/kagglesdk/competitions/types/host_service.py @@ -46,6 +46,9 @@ class CompetitionSettings(KaggleObject): deadline (datetime) KEY DATES SETTINGS GROUP (field numbers 40-59) 'Competition Deadline' in the UI. + private_leaderboard_release_date (datetime) + 'Private Leaderboard Release Date' in the UI. When set, must fall between + the deadline and 7 days after it. team_merger_explicit_deadline (datetime) KEY DATES SETTINGS GROUP: ADMIN ONLY 'Team Merger Deadline' in the UI. @@ -117,6 +120,7 @@ def __init__(self): self._enable_team_files = False self._team_file_deadline = None self._deadline = None + self._private_leaderboard_release_date = None self._team_merger_explicit_deadline = None self._prohibit_new_entrants_explicit_deadline = None self._kernels_publishing_disabled_deadline = None @@ -320,6 +324,23 @@ def deadline(self, deadline: datetime): raise TypeError('deadline must be of type datetime') self._deadline = deadline + @property + def private_leaderboard_release_date(self) -> datetime: + r""" + 'Private Leaderboard Release Date' in the UI. When set, must fall between + the deadline and 7 days after it. + """ + return self._private_leaderboard_release_date + + @private_leaderboard_release_date.setter + def private_leaderboard_release_date(self, private_leaderboard_release_date: datetime): + if private_leaderboard_release_date is None: + del self.private_leaderboard_release_date + return + if not isinstance(private_leaderboard_release_date, datetime): + raise TypeError('private_leaderboard_release_date must be of type datetime') + self._private_leaderboard_release_date = private_leaderboard_release_date + @property def team_merger_explicit_deadline(self) -> datetime: r""" @@ -626,6 +647,7 @@ def directly_responsible_user_id(self, directly_responsible_user_id: Optional[in FieldMetadata("enableTeamFiles", "enable_team_files", "_enable_team_files", bool, False, PredefinedSerializer()), FieldMetadata("teamFileDeadline", "team_file_deadline", "_team_file_deadline", datetime, None, DateTimeSerializer()), FieldMetadata("deadline", "deadline", "_deadline", datetime, None, DateTimeSerializer()), + FieldMetadata("privateLeaderboardReleaseDate", "private_leaderboard_release_date", "_private_leaderboard_release_date", datetime, None, DateTimeSerializer()), FieldMetadata("teamMergerExplicitDeadline", "team_merger_explicit_deadline", "_team_merger_explicit_deadline", datetime, None, DateTimeSerializer()), FieldMetadata("prohibitNewEntrantsExplicitDeadline", "prohibit_new_entrants_explicit_deadline", "_prohibit_new_entrants_explicit_deadline", datetime, None, DateTimeSerializer()), FieldMetadata("kernelsPublishingDisabledDeadline", "kernels_publishing_disabled_deadline", "_kernels_publishing_disabled_deadline", datetime, None, DateTimeSerializer()), diff --git a/kagglesdk/security/types/security_types.py b/kagglesdk/security/types/security_types.py index 2826586..b7b05ef 100644 --- a/kagglesdk/security/types/security_types.py +++ b/kagglesdk/security/types/security_types.py @@ -38,6 +38,7 @@ class KaggleResourceType(enum.Enum): KAGGLE_RESOURCE_TYPE_RESOURCE_ACCESS_GROUPS = 140 KAGGLE_RESOURCE_TYPE_OPERATIONS = 142 KAGGLE_RESOURCE_TYPE_AGENT_EXAMS = 144 + KAGGLE_RESOURCE_TYPE_RESOURCE_FILTER_SCOPES = 146 KAGGLE_RESOURCE_TYPE_FORUMS = 200 """---------- Community ----------""" KAGGLE_RESOURCE_TYPE_FORUM_TOPICS = 202 diff --git a/kagglesdk/users/types/account_service.py b/kagglesdk/users/types/account_service.py index 40084a1..950b1f9 100644 --- a/kagglesdk/users/types/account_service.py +++ b/kagglesdk/users/types/account_service.py @@ -133,6 +133,19 @@ class GenerateAccessTokenRequest(KaggleObject): Set of scopes to further restrict the token. If 'refresh_token' is specified, these should be a subset of the scopes allowed by the 'refresh_token'. + resource_filter_scope_id (int) + Id of a ResourceFilterScopes row (go/kaggle-agent-augmented-identities). + Confines the minted token to that scope: a caller presenting the token only + sees rows filed under it, and every scoped row it writes is stamped with + it. Owner-only, enforced by the RESOURCE_FILTER_SCOPES_USE checker rather + than by the handler, and additionally gated on the + ENABLE_RESOURCE_FILTER_SCOPES flag. + + Only valid for short-lived access tokens minted from the caller's own + credentials. Combining it with 'refresh_token' is rejected: scopes are + burned into the access token rather than persisted on the refresh token, so + there would be nothing to inherit and the caller minting the token need not + be the refresh token's owner. """ def __init__(self): @@ -141,6 +154,7 @@ def __init__(self): self._expiration_duration = None self._authorization_context = None self._authorization_scopes = [] + self._resource_filter_scope_id = None self._freeze() @property @@ -223,6 +237,33 @@ def authorization_scopes(self, authorization_scopes: Optional[List[Optional['Aut raise TypeError('authorization_scopes must contain only items of type AuthorizationScope') self._authorization_scopes = authorization_scopes + @property + def resource_filter_scope_id(self) -> int: + r""" + Id of a ResourceFilterScopes row (go/kaggle-agent-augmented-identities). + Confines the minted token to that scope: a caller presenting the token only + sees rows filed under it, and every scoped row it writes is stamped with + it. Owner-only, enforced by the RESOURCE_FILTER_SCOPES_USE checker rather + than by the handler, and additionally gated on the + ENABLE_RESOURCE_FILTER_SCOPES flag. + + Only valid for short-lived access tokens minted from the caller's own + credentials. Combining it with 'refresh_token' is rejected: scopes are + burned into the access token rather than persisted on the refresh token, so + there would be nothing to inherit and the caller minting the token need not + be the refresh token's owner. + """ + return self._resource_filter_scope_id or 0 + + @resource_filter_scope_id.setter + def resource_filter_scope_id(self, resource_filter_scope_id: Optional[int]): + if resource_filter_scope_id is None: + del self.resource_filter_scope_id + return + if not isinstance(resource_filter_scope_id, int): + raise TypeError('resource_filter_scope_id must be of type int') + self._resource_filter_scope_id = resource_filter_scope_id + def endpoint(self): path = '/api/v1/access-tokens/generate' return path.format_map(self.to_field_map(self)) @@ -334,6 +375,7 @@ def userId(self): FieldMetadata("expirationDuration", "expiration_duration", "_expiration_duration", timedelta, None, TimeDeltaSerializer()), FieldMetadata("authorizationContext", "authorization_context", "_authorization_context", AuthorizationContext, None, KaggleObjectSerializer()), FieldMetadata("authorizationScopes", "authorization_scopes", "_authorization_scopes", AuthorizationScope, [], ListSerializer(KaggleObjectSerializer())), + FieldMetadata("resourceFilterScopeId", "resource_filter_scope_id", "_resource_filter_scope_id", int, None, PredefinedSerializer(), optional=True), ] GenerateAccessTokenResponse._fields = [