diff --git a/kagglesdk/__init__.py b/kagglesdk/__init__.py index 0da479b..5fcc066 100644 --- a/kagglesdk/__init__.py +++ b/kagglesdk/__init__.py @@ -1,4 +1,4 @@ -__version__ = "0.1.33" +__version__ = "0.1.34" from kagglesdk.kaggle_client import KaggleClient from kagglesdk.kaggle_creds import KaggleCredentials diff --git a/kagglesdk/competitions/services/competition_api_service.py b/kagglesdk/competitions/services/competition_api_service.py index 9f635c2..14ee901 100644 --- a/kagglesdk/competitions/services/competition_api_service.py +++ b/kagglesdk/competitions/services/competition_api_service.py @@ -1,6 +1,6 @@ from kagglesdk.common.types.file_download import FileDownload from kagglesdk.common.types.http_redirect import HttpRedirect -from kagglesdk.competitions.types.competition_api_service import ApiCompetition, ApiCompetitionPage, ApiCreateCodeSubmissionRequest, ApiCreateCodeSubmissionResponse, ApiCreateCompetitionDataRequest, ApiCreateCompetitionDataResponse, ApiCreateCompetitionPageRequest, ApiCreateCompetitionRequest, ApiCreateCompetitionResponse, ApiCreateCompetitionSolutionRequest, ApiCreateSubmissionRequest, ApiCreateSubmissionResponse, ApiDeleteCompetitionPageRequest, ApiDownloadDataFileRequest, ApiDownloadDataFilesRequest, ApiDownloadLeaderboardRequest, ApiGetCompetitionDataFilesSummaryRequest, ApiGetCompetitionRequest, ApiGetEpisodeAgentLogsRequest, ApiGetEpisodeReplayRequest, ApiGetLeaderboardRequest, ApiGetLeaderboardResponse, ApiGetSubmissionRequest, ApiLaunchCompetitionRequest, ApiListCompetitionPagesRequest, ApiListCompetitionPagesResponse, ApiListCompetitionsRequest, ApiListCompetitionsResponse, ApiListCompetitionTopicsRequest, ApiListCompetitionTopicsResponse, ApiListDataFilesRequest, ApiListDataFilesResponse, ApiListDataTreeFilesRequest, ApiListSubmissionEpisodesRequest, ApiListSubmissionEpisodesResponse, ApiListSubmissionsRequest, ApiListSubmissionsResponse, ApiListTeamPublicSubmissionsRequest, ApiListTeamPublicSubmissionsResponse, ApiListTopicMessagesRequest, ApiListTopicMessagesResponse, ApiStartSubmissionUploadRequest, ApiStartSubmissionUploadResponse, ApiSubmission, ApiUpdateCompetitionPageRequest, ApiUpdateCompetitionSettingsRequest +from kagglesdk.competitions.types.competition_api_service import ApiCompetition, ApiCompetitionPage, ApiCompetitionSolutionStatus, ApiCreateCodeSubmissionRequest, ApiCreateCodeSubmissionResponse, ApiCreateCompetitionDataRequest, ApiCreateCompetitionDataResponse, ApiCreateCompetitionPageRequest, ApiCreateCompetitionRequest, ApiCreateCompetitionResponse, ApiCreateCompetitionSampleSubmissionRequest, ApiCreateCompetitionSolutionRequest, ApiCreateSubmissionRequest, ApiCreateSubmissionResponse, ApiDeleteCompetitionPageRequest, ApiDownloadDataFileRequest, ApiDownloadDataFilesRequest, ApiDownloadLeaderboardRequest, ApiGetCompetitionDataFilesSummaryRequest, ApiGetCompetitionRequest, ApiGetCompetitionSettingsRequest, ApiGetCompetitionSolutionStatusRequest, ApiGetEpisodeAgentLogsRequest, ApiGetEpisodeReplayRequest, ApiGetLeaderboardRequest, ApiGetLeaderboardResponse, ApiGetSubmissionRequest, ApiLaunchCompetitionRequest, ApiListCompetitionHostsRequest, ApiListCompetitionHostsResponse, ApiListCompetitionPagesRequest, ApiListCompetitionPagesResponse, ApiListCompetitionsRequest, ApiListCompetitionsResponse, ApiListCompetitionTopicsRequest, ApiListCompetitionTopicsResponse, ApiListDataFilesRequest, ApiListDataFilesResponse, ApiListDataTreeFilesRequest, ApiListSubmissionEpisodesRequest, ApiListSubmissionEpisodesResponse, ApiListSubmissionsRequest, ApiListSubmissionsResponse, ApiListTeamPublicSubmissionsRequest, ApiListTeamPublicSubmissionsResponse, ApiListTopicMessagesRequest, ApiListTopicMessagesResponse, ApiStartSubmissionUploadRequest, ApiStartSubmissionUploadResponse, ApiSubmission, ApiUpdateCompetitionPageRequest, ApiUpdateCompetitionSettingsRequest from kagglesdk.competitions.types.host_service import CompetitionSettings from kagglesdk.datasets.databundles.types.databundle_api_types import ApiDirectoryContent, ApiFilesSummary from kagglesdk.kaggle_http_client import KaggleHttpClient @@ -298,6 +298,18 @@ def update_competition_settings(self, request: ApiUpdateCompetitionSettingsReque return self._client.call("competitions.CompetitionApiService", "UpdateCompetitionSettings", request, CompetitionSettings) + def get_competition_settings(self, request: ApiGetCompetitionSettingsRequest = None) -> CompetitionSettings: + r""" + Args: + request (ApiGetCompetitionSettingsRequest): + The request object; initialized to empty instance if not specified. + """ + + if request is None: + request = ApiGetCompetitionSettingsRequest() + + return self._client.call("competitions.CompetitionApiService", "GetCompetitionSettings", request, CompetitionSettings) + def launch_competition(self, request: ApiLaunchCompetitionRequest = None): r""" Args: @@ -342,6 +354,46 @@ def create_competition_solution(self, request: ApiCreateCompetitionSolutionReque self._client.call("competitions.CompetitionApiService", "CreateCompetitionSolution", request, None) + def get_competition_solution_status(self, request: ApiGetCompetitionSolutionStatusRequest = None) -> ApiCompetitionSolutionStatus: + r""" + Args: + request (ApiGetCompetitionSolutionStatusRequest): + The request object; initialized to empty instance if not specified. + """ + + if request is None: + request = ApiGetCompetitionSolutionStatusRequest() + + return self._client.call("competitions.CompetitionApiService", "GetCompetitionSolutionStatus", request, ApiCompetitionSolutionStatus) + + def create_competition_sample_submission(self, request: ApiCreateCompetitionSampleSubmissionRequest = None): + r""" + Not MCP-exported: the prerequisite blob upload step (start_blob_upload + + signed-URL PUT) has no MCP equivalent, so the tool would be unusable from + MCP clients today. Public REST + Python SDK only; the kaggle CLI drives it. + + Args: + request (ApiCreateCompetitionSampleSubmissionRequest): + The request object; initialized to empty instance if not specified. + """ + + if request is None: + request = ApiCreateCompetitionSampleSubmissionRequest() + + self._client.call("competitions.CompetitionApiService", "CreateCompetitionSampleSubmission", request, None) + + def list_competition_hosts(self, request: ApiListCompetitionHostsRequest = None) -> ApiListCompetitionHostsResponse: + r""" + Args: + request (ApiListCompetitionHostsRequest): + The request object; initialized to empty instance if not specified. + """ + + if request is None: + request = ApiListCompetitionHostsRequest() + + return self._client.call("competitions.CompetitionApiService", "ListCompetitionHosts", request, ApiListCompetitionHostsResponse) + def list_competition_topics(self, request: ApiListCompetitionTopicsRequest = None) -> ApiListCompetitionTopicsResponse: r""" Args: diff --git a/kagglesdk/competitions/types/competition.py b/kagglesdk/competitions/types/competition.py index 787a0d3..d6979fb 100644 --- a/kagglesdk/competitions/types/competition.py +++ b/kagglesdk/competitions/types/competition.py @@ -29,6 +29,7 @@ class RewardTypeId(enum.Enum): GBP = 7 KNOWLEDGE = 8 PRIZES = 9 + NON_MONETARY = 10 class Reward(KaggleObject): r""" diff --git a/kagglesdk/competitions/types/competition_api_service.py b/kagglesdk/competitions/types/competition_api_service.py index 0d4c193..4bcaa88 100644 --- a/kagglesdk/competitions/types/competition_api_service.py +++ b/kagglesdk/competitions/types/competition_api_service.py @@ -7,7 +7,7 @@ from kagglesdk.competitions.types.submission_status import SubmissionStatus from kagglesdk.discussions.types.discussions_enums import CommentListSortBy, TopicListSortBy from kagglesdk.kaggle_object import * -from typing import Optional, List +from typing import Optional, List, Dict class ApiCategory(KaggleObject): r""" @@ -603,6 +603,83 @@ def token(self, token: str): self._token = token +class ApiCompetitionHost(KaggleObject): + r""" + Attributes: + id (int) + Numeric user ID. + user_name (str) + Kaggle user name (URL slug, e.g. 'fickleone'). + display_name (str) + Human-readable display name. + profile_url (str) + Full URL to the user's profile page. + """ + + def __init__(self): + self._id = 0 + self._user_name = None + self._display_name = None + self._profile_url = None + self._freeze() + + @property + def id(self) -> int: + """Numeric user ID.""" + return self._id + + @id.setter + def id(self, id: int): + if id is None: + del self.id + return + if not isinstance(id, int): + raise TypeError('id must be of type int') + self._id = id + + @property + def user_name(self) -> str: + """Kaggle user name (URL slug, e.g. 'fickleone').""" + return self._user_name or "" + + @user_name.setter + def user_name(self, user_name: Optional[str]): + if user_name is None: + del self.user_name + return + if not isinstance(user_name, str): + raise TypeError('user_name must be of type str') + self._user_name = user_name + + @property + def display_name(self) -> str: + """Human-readable display name.""" + return self._display_name or "" + + @display_name.setter + def display_name(self, display_name: Optional[str]): + if display_name is None: + del self.display_name + return + if not isinstance(display_name, str): + raise TypeError('display_name must be of type str') + self._display_name = display_name + + @property + def profile_url(self) -> str: + """Full URL to the user's profile page.""" + return self._profile_url or "" + + @profile_url.setter + def profile_url(self, profile_url: Optional[str]): + if profile_url is None: + del self.profile_url + return + if not isinstance(profile_url, str): + raise TypeError('profile_url must be of type str') + self._profile_url = profile_url + + class ApiCompetitionPage(KaggleObject): r""" NOTE: writable field names must stay in sync with `kaggle.competitions.Page` @@ -712,6 +789,172 @@ def mime_type(self, mime_type: Optional[str]): self._mime_type = mime_type +class ApiCompetitionSolutionStatus(KaggleObject): + r""" + Attributes: + ready (bool) + True once all required setup steps for the solution file are complete and + the competition can score submissions. Poll this after + CreateCompetitionData / CreateCompetitionSolution until it flips true (or + `setup_error` is set). + setup_error (str) + Populated if preprocessing or sampling failed. The CLI should surface + this message and stop polling. + kernels_metric (bool) + True if the competition's scoring metric is Kernels-based. Kernels metrics + auto-detect their column mapping and `column_mapping` / + `required_metric_columns` are not used -- the host only needs to wait + for `ready` to flip true. + row_id_column_name (str) + For Kernels metrics only -- the row-id column auto-detected from the CSV. + column_mapping (str) + For legacy C# metrics: the current mapping from metric column name to + CSV column name. Populated with the auto-inferred mapping after + preprocessing completes; empty before that. The host commits the final + mapping by passing the same shape to UpdateCompetitionSolutionMapping. + required_metric_columns (ApiMetricColumn) + For legacy C# metrics: the metric column slots the host needs to fill. + Each entry's `name` is a key for `column_mapping`; `data_type` is the + expected parsed type (e.g. 'Double', 'Int32'). + solution_info (ApiSolutionFileInfo) + Solution file metadata. Null until a solution has been uploaded. + """ + + def __init__(self): + self._ready = False + self._setup_error = None + self._kernels_metric = False + self._row_id_column_name = None + self._column_mapping = {} + self._required_metric_columns = [] + self._solution_info = None + self._freeze() + + @property + def ready(self) -> bool: + r""" + True once all required setup steps for the solution file are complete and + the competition can score submissions. Poll this after + CreateCompetitionData / CreateCompetitionSolution until it flips true (or + `setup_error` is set). + """ + return self._ready + + @ready.setter + def ready(self, ready: bool): + if ready is None: + del self.ready + return + if not isinstance(ready, bool): + raise TypeError('ready must be of type bool') + self._ready = ready + + @property + def setup_error(self) -> str: + r""" + Populated if preprocessing or sampling failed. The CLI should surface + this message and stop polling. + """ + return self._setup_error or "" + + @setup_error.setter + def setup_error(self, setup_error: Optional[str]): + if setup_error is None: + del self.setup_error + return + if not isinstance(setup_error, str): + raise TypeError('setup_error must be of type str') + self._setup_error = setup_error + + @property + def kernels_metric(self) -> bool: + r""" + True if the competition's scoring metric is Kernels-based. Kernels metrics + auto-detect their column mapping and `column_mapping` / + `required_metric_columns` are not used -- the host only needs to wait + for `ready` to flip true. + """ + return self._kernels_metric + + @kernels_metric.setter + def kernels_metric(self, kernels_metric: bool): + if kernels_metric is None: + del self.kernels_metric + return + if not isinstance(kernels_metric, bool): + raise TypeError('kernels_metric must be of type bool') + self._kernels_metric = kernels_metric + + @property + def row_id_column_name(self) -> str: + """For Kernels metrics only -- the row-id column auto-detected from the CSV.""" + return self._row_id_column_name or "" + + @row_id_column_name.setter + def row_id_column_name(self, row_id_column_name: Optional[str]): + if row_id_column_name is None: + del self.row_id_column_name + return + if not isinstance(row_id_column_name, str): + raise TypeError('row_id_column_name must be of type str') + self._row_id_column_name = row_id_column_name + + @property + def column_mapping(self) -> Optional[Dict[str, str]]: + r""" + For legacy C# metrics: the current mapping from metric column name to + CSV column name. Populated with the auto-inferred mapping after + preprocessing completes; empty before that. The host commits the final + mapping by passing the same shape to UpdateCompetitionSolutionMapping. + """ + return self._column_mapping + + @column_mapping.setter + def column_mapping(self, column_mapping: Optional[Dict[str, str]]): + if column_mapping is None: + del self.column_mapping + return + if not isinstance(column_mapping, dict): + raise TypeError('column_mapping must be of type dict') + if not all([isinstance(v, str) for k, v in column_mapping]): + raise TypeError('column_mapping must contain only items of type str') + self._column_mapping = column_mapping + + @property + def required_metric_columns(self) -> Optional[List[Optional['ApiMetricColumn']]]: + r""" + For legacy C# metrics: the metric column slots the host needs to fill. + Each entry's `name` is a key for `column_mapping`; `data_type` is the + expected parsed type (e.g. 'Double', 'Int32'). + """ + return self._required_metric_columns + + @required_metric_columns.setter + def required_metric_columns(self, required_metric_columns: Optional[List[Optional['ApiMetricColumn']]]): + if required_metric_columns is None: + del self.required_metric_columns + return + if not isinstance(required_metric_columns, list): + raise TypeError('required_metric_columns must be of type list') + if not all([isinstance(t, ApiMetricColumn) for t in required_metric_columns]): + raise TypeError('required_metric_columns must contain only items of type ApiMetricColumn') + self._required_metric_columns = required_metric_columns + + @property + def solution_info(self) -> Optional['ApiSolutionFileInfo']: + """Solution file metadata. Null until a solution has been uploaded.""" + return self._solution_info + + @solution_info.setter + def solution_info(self, solution_info: Optional['ApiSolutionFileInfo']): + if solution_info is None: + del self.solution_info + return + if not isinstance(solution_info, ApiSolutionFileInfo): + raise TypeError('solution_info must be of type ApiSolutionFileInfo') + self._solution_info = solution_info + + class ApiCompetitionTopic(KaggleObject): r""" Attributes: @@ -1565,6 +1808,66 @@ def url(self, url: str): self._url = url +class ApiCreateCompetitionSampleSubmissionRequest(KaggleObject): + r""" + Attributes: + competition_name (str) + blob_token (str) + Blob token returned by /api/v1/blobs/upload after the matching upload PUT. + The blob must be a CSV in the same shape as a regular submission. The + submission lands on the sandbox team and is scored asynchronously. + """ + + def __init__(self): + self._competition_name = "" + self._blob_token = "" + self._freeze() + + @property + def competition_name(self) -> str: + return self._competition_name + + @competition_name.setter + def competition_name(self, competition_name: 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 + + @property + def blob_token(self) -> str: + r""" + Blob token returned by /api/v1/blobs/upload after the matching upload PUT. + The blob must be a CSV in the same shape as a regular submission. The + submission lands on the sandbox team and is scored asynchronously. + """ + return self._blob_token + + @blob_token.setter + def blob_token(self, blob_token: str): + if blob_token is None: + del self.blob_token + return + if not isinstance(blob_token, str): + raise TypeError('blob_token must be of type str') + self._blob_token = blob_token + + def endpoint(self): + path = '/api/v1/competitions/{competition_name}/sample-submission' + return path.format_map(self.to_field_map(self)) + + + @staticmethod + def method(): + return 'POST' + + @staticmethod + def body_fields(): + return '*' + + class ApiCreateCompetitionSolutionRequest(KaggleObject): r""" Attributes: @@ -2309,6 +2612,70 @@ def endpoint_path(): return '/api/v1/competitions/get/{competition_name}' +class ApiGetCompetitionSettingsRequest(KaggleObject): + r""" + Attributes: + competition_name (str) + """ + + def __init__(self): + self._competition_name = "" + self._freeze() + + @property + def competition_name(self) -> str: + return self._competition_name + + @competition_name.setter + def competition_name(self, competition_name: 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_name}/settings' + return path.format_map(self.to_field_map(self)) + + @staticmethod + def endpoint_path(): + return '/api/v1/competitions/{competition_name}/settings' + + +class ApiGetCompetitionSolutionStatusRequest(KaggleObject): + r""" + Attributes: + competition_name (str) + """ + + def __init__(self): + self._competition_name = "" + self._freeze() + + @property + def competition_name(self) -> str: + return self._competition_name + + @competition_name.setter + def competition_name(self, competition_name: 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_name}/solution' + return path.format_map(self.to_field_map(self)) + + @staticmethod + def endpoint_path(): + return '/api/v1/competitions/{competition_name}/solution' + + class ApiGetEpisodeAgentLogsRequest(KaggleObject): r""" Attributes: @@ -2682,6 +3049,64 @@ def score(self, score: Optional[str]): self._score = score +class ApiListCompetitionHostsRequest(KaggleObject): + r""" + Attributes: + competition_name (str) + """ + + def __init__(self): + self._competition_name = "" + self._freeze() + + @property + def competition_name(self) -> str: + return self._competition_name + + @competition_name.setter + def competition_name(self, competition_name: 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_name}/hosts' + return path.format_map(self.to_field_map(self)) + + @staticmethod + def endpoint_path(): + return '/api/v1/competitions/{competition_name}/hosts' + + +class ApiListCompetitionHostsResponse(KaggleObject): + r""" + Attributes: + hosts (ApiCompetitionHost) + """ + + def __init__(self): + self._hosts = [] + self._freeze() + + @property + def hosts(self) -> Optional[List[Optional['ApiCompetitionHost']]]: + return self._hosts + + @hosts.setter + def hosts(self, hosts: Optional[List[Optional['ApiCompetitionHost']]]): + if hosts is None: + del self.hosts + return + if not isinstance(hosts, list): + raise TypeError('hosts must be of type list') + if not all([isinstance(t, ApiCompetitionHost) for t in hosts]): + raise TypeError('hosts must contain only items of type ApiCompetitionHost') + self._hosts = hosts + + class ApiListCompetitionPagesRequest(KaggleObject): r""" Attributes: @@ -3653,6 +4078,45 @@ def messages(self, messages: Optional[List[Optional['ApiTopicMessage']]]): self._messages = messages +class ApiMetricColumn(KaggleObject): + r""" + Attributes: + name (str) + data_type (str) + """ + + def __init__(self): + self._name = "" + self._data_type = "" + self._freeze() + + @property + def name(self) -> str: + return self._name + + @name.setter + def name(self, name: str): + if name is None: + del self.name + return + if not isinstance(name, str): + raise TypeError('name must be of type str') + self._name = name + + @property + def data_type(self) -> str: + return self._data_type + + @data_type.setter + def data_type(self, data_type: str): + if data_type is None: + del self.data_type + return + if not isinstance(data_type, str): + raise TypeError('data_type must be of type str') + self._data_type = data_type + + class ApiPublicSubmission(KaggleObject): r""" Public-safe subset of a submission. Only fields safe to expose to any user @@ -3710,6 +4174,105 @@ def public_score(self, public_score: str): self._public_score = public_score +class ApiSolutionFileInfo(KaggleObject): + r""" + Attributes: + file_name (str) + file_size_bytes (int) + upload_date (datetime) + total_rows (int) + public_rows (int) + private_rows (int) + """ + + def __init__(self): + self._file_name = None + self._file_size_bytes = None + self._upload_date = None + self._total_rows = None + self._public_rows = None + self._private_rows = None + self._freeze() + + @property + def file_name(self) -> str: + return self._file_name or "" + + @file_name.setter + def file_name(self, file_name: Optional[str]): + if file_name is None: + del self.file_name + return + if not isinstance(file_name, str): + raise TypeError('file_name must be of type str') + self._file_name = file_name + + @property + def file_size_bytes(self) -> int: + return self._file_size_bytes or 0 + + @file_size_bytes.setter + def file_size_bytes(self, file_size_bytes: Optional[int]): + if file_size_bytes is None: + del self.file_size_bytes + return + if not isinstance(file_size_bytes, int): + raise TypeError('file_size_bytes must be of type int') + self._file_size_bytes = file_size_bytes + + @property + def upload_date(self) -> datetime: + return self._upload_date + + @upload_date.setter + def upload_date(self, upload_date: datetime): + if upload_date is None: + del self.upload_date + return + if not isinstance(upload_date, datetime): + raise TypeError('upload_date must be of type datetime') + self._upload_date = upload_date + + @property + def total_rows(self) -> int: + return self._total_rows or 0 + + @total_rows.setter + def total_rows(self, total_rows: Optional[int]): + if total_rows is None: + del self.total_rows + return + if not isinstance(total_rows, int): + raise TypeError('total_rows must be of type int') + self._total_rows = total_rows + + @property + def public_rows(self) -> int: + return self._public_rows or 0 + + @public_rows.setter + def public_rows(self, public_rows: Optional[int]): + if public_rows is None: + del self.public_rows + return + if not isinstance(public_rows, int): + raise TypeError('public_rows must be of type int') + self._public_rows = public_rows + + @property + def private_rows(self) -> int: + return self._private_rows or 0 + + @private_rows.setter + def private_rows(self, private_rows: Optional[int]): + if private_rows is None: + del self.private_rows + return + if not isinstance(private_rows, int): + raise TypeError('private_rows must be of type int') + self._private_rows = private_rows + + class ApiStartSubmissionUploadRequest(KaggleObject): r""" Attributes: @@ -4413,6 +4976,13 @@ def body_fields(): FieldMetadata("token", "token", "_token", str, "", PredefinedSerializer()), ] +ApiCompetitionHost._fields = [ + FieldMetadata("id", "id", "_id", int, 0, PredefinedSerializer()), + FieldMetadata("userName", "user_name", "_user_name", str, None, PredefinedSerializer(), optional=True), + FieldMetadata("displayName", "display_name", "_display_name", str, None, PredefinedSerializer(), optional=True), + FieldMetadata("profileUrl", "profile_url", "_profile_url", str, None, PredefinedSerializer(), optional=True), +] + ApiCompetitionPage._fields = [ FieldMetadata("name", "name", "_name", str, "", PredefinedSerializer()), FieldMetadata("content", "content", "_content", str, "", PredefinedSerializer()), @@ -4421,6 +4991,16 @@ def body_fields(): FieldMetadata("mimeType", "mime_type", "_mime_type", str, None, PredefinedSerializer(), optional=True), ] +ApiCompetitionSolutionStatus._fields = [ + FieldMetadata("ready", "ready", "_ready", bool, False, PredefinedSerializer()), + FieldMetadata("setupError", "setup_error", "_setup_error", str, None, PredefinedSerializer(), optional=True), + FieldMetadata("kernelsMetric", "kernels_metric", "_kernels_metric", bool, False, PredefinedSerializer()), + FieldMetadata("rowIdColumnName", "row_id_column_name", "_row_id_column_name", str, None, PredefinedSerializer(), optional=True), + FieldMetadata("columnMapping", "column_mapping", "_column_mapping", str, {}, MapSerializer(PredefinedSerializer())), + FieldMetadata("requiredMetricColumns", "required_metric_columns", "_required_metric_columns", ApiMetricColumn, [], ListSerializer(KaggleObjectSerializer())), + FieldMetadata("solutionInfo", "solution_info", "_solution_info", ApiSolutionFileInfo, None, KaggleObjectSerializer()), +] + ApiCompetitionTopic._fields = [ FieldMetadata("id", "id", "_id", int, 0, PredefinedSerializer()), FieldMetadata("title", "title", "_title", str, "", PredefinedSerializer()), @@ -4488,6 +5068,11 @@ def body_fields(): FieldMetadata("url", "url", "_url", str, "", PredefinedSerializer()), ] +ApiCreateCompetitionSampleSubmissionRequest._fields = [ + FieldMetadata("competitionName", "competition_name", "_competition_name", str, "", PredefinedSerializer()), + FieldMetadata("blobToken", "blob_token", "_blob_token", str, "", PredefinedSerializer()), +] + ApiCreateCompetitionSolutionRequest._fields = [ FieldMetadata("competitionName", "competition_name", "_competition_name", str, "", PredefinedSerializer()), FieldMetadata("blobToken", "blob_token", "_blob_token", str, "", PredefinedSerializer()), @@ -4559,6 +5144,14 @@ def body_fields(): FieldMetadata("competitionName", "competition_name", "_competition_name", str, "", PredefinedSerializer()), ] +ApiGetCompetitionSettingsRequest._fields = [ + FieldMetadata("competitionName", "competition_name", "_competition_name", str, "", PredefinedSerializer()), +] + +ApiGetCompetitionSolutionStatusRequest._fields = [ + FieldMetadata("competitionName", "competition_name", "_competition_name", str, "", PredefinedSerializer()), +] + ApiGetEpisodeAgentLogsRequest._fields = [ FieldMetadata("episodeId", "episode_id", "_episode_id", int, 0, PredefinedSerializer()), FieldMetadata("agentIndex", "agent_index", "_agent_index", int, 0, PredefinedSerializer()), @@ -4596,6 +5189,14 @@ def body_fields(): FieldMetadata("score", "score", "_score", str, None, PredefinedSerializer(), optional=True), ] +ApiListCompetitionHostsRequest._fields = [ + FieldMetadata("competitionName", "competition_name", "_competition_name", str, "", PredefinedSerializer()), +] + +ApiListCompetitionHostsResponse._fields = [ + FieldMetadata("hosts", "hosts", "_hosts", ApiCompetitionHost, [], ListSerializer(KaggleObjectSerializer())), +] + ApiListCompetitionPagesRequest._fields = [ FieldMetadata("competitionName", "competition_name", "_competition_name", str, "", PredefinedSerializer()), FieldMetadata("pageName", "page_name", "_page_name", str, None, PredefinedSerializer(), optional=True), @@ -4691,12 +5292,26 @@ def body_fields(): FieldMetadata("messages", "messages", "_messages", ApiTopicMessage, [], ListSerializer(KaggleObjectSerializer())), ] +ApiMetricColumn._fields = [ + FieldMetadata("name", "name", "_name", str, "", PredefinedSerializer()), + FieldMetadata("dataType", "data_type", "_data_type", str, "", PredefinedSerializer()), +] + ApiPublicSubmission._fields = [ FieldMetadata("id", "id", "_id", int, 0, PredefinedSerializer()), FieldMetadata("dateSubmitted", "date_submitted", "_date_submitted", datetime, None, DateTimeSerializer()), FieldMetadata("publicScore", "public_score", "_public_score", str, "", PredefinedSerializer()), ] +ApiSolutionFileInfo._fields = [ + FieldMetadata("fileName", "file_name", "_file_name", str, None, PredefinedSerializer(), optional=True), + FieldMetadata("fileSizeBytes", "file_size_bytes", "_file_size_bytes", int, None, PredefinedSerializer(), optional=True), + FieldMetadata("uploadDate", "upload_date", "_upload_date", datetime, None, DateTimeSerializer()), + FieldMetadata("totalRows", "total_rows", "_total_rows", int, None, PredefinedSerializer(), optional=True), + FieldMetadata("publicRows", "public_rows", "_public_rows", int, None, PredefinedSerializer(), optional=True), + FieldMetadata("privateRows", "private_rows", "_private_rows", int, None, PredefinedSerializer(), optional=True), +] + ApiStartSubmissionUploadRequest._fields = [ FieldMetadata("competitionName", "competition_name", "_competition_name", str, None, PredefinedSerializer(), optional=True), FieldMetadata("contentLength", "content_length", "_content_length", int, 0, PredefinedSerializer()), diff --git a/kagglesdk/competitions/types/hackathons.py b/kagglesdk/competitions/types/hackathons.py index 950486a..ed42a27 100644 --- a/kagglesdk/competitions/types/hackathons.py +++ b/kagglesdk/competitions/types/hackathons.py @@ -201,6 +201,9 @@ class HackathonWriteUp(KaggleObject): competition_id (int) owner_host_user_id (int) owner_judge_user_id (int) + should_create_doi (bool) + Whether or not the user indicated a DOI should be created for the hackathon + writeup when the competition closes. """ def __init__(self): @@ -213,6 +216,7 @@ def __init__(self): self._competition_id = 0 self._owner_host_user_id = None self._owner_judge_user_id = None + self._should_create_doi = None self._freeze() @property @@ -336,6 +340,23 @@ def owner_judge_user_id(self, owner_judge_user_id: Optional[int]): raise TypeError('owner_judge_user_id must be of type int') self._owner_judge_user_id = owner_judge_user_id + @property + def should_create_doi(self) -> bool: + r""" + Whether or not the user indicated a DOI should be created for the hackathon + writeup when the competition closes. + """ + return self._should_create_doi or False + + @should_create_doi.setter + def should_create_doi(self, should_create_doi: Optional[bool]): + if should_create_doi is None: + del self.should_create_doi + return + if not isinstance(should_create_doi, bool): + raise TypeError('should_create_doi must be of type bool') + self._should_create_doi = should_create_doi + HackathonTrack._fields = [ FieldMetadata("id", "id", "_id", int, 0, PredefinedSerializer()), @@ -364,5 +385,6 @@ def owner_judge_user_id(self, owner_judge_user_id: Optional[int]): FieldMetadata("competitionId", "competition_id", "_competition_id", int, 0, PredefinedSerializer()), FieldMetadata("ownerHostUserId", "owner_host_user_id", "_owner_host_user_id", int, None, PredefinedSerializer(), optional=True), FieldMetadata("ownerJudgeUserId", "owner_judge_user_id", "_owner_judge_user_id", int, None, PredefinedSerializer(), optional=True), + FieldMetadata("shouldCreateDoi", "should_create_doi", "_should_create_doi", bool, None, PredefinedSerializer(), optional=True), ] diff --git a/kagglesdk/competitions/types/host_service.py b/kagglesdk/competitions/types/host_service.py index 45b3071..293a405 100644 --- a/kagglesdk/competitions/types/host_service.py +++ b/kagglesdk/competitions/types/host_service.py @@ -87,6 +87,18 @@ class CompetitionSettings(KaggleObject): Host-authored template Notebook the frontend wraps the user's artifact (e.g. skill.md) into before submitting. Parallels main_py_override_kernel_id. + gateway_kernel_id (int) + 'Gateway Kernel Id' in the UI. Identifies the notebook whose latest + version is used as the source for the parent (gateway) container in + go/project-hearth rerun sessions. + rerun_max_stagger_minutes (float) + 'Rerun Max Stagger Minutes' in the UI. Random delay added before a + scoring run kicks off (sampled from 0..this value, clamped to 60). Used + for sync-rerun / Hearth competitions to limit private dataset probing. + directly_responsible_user_id (int) + HOSTS SETTINGS GROUP: ADMIN ONLY (field numbers 120-139) + 'Directly Responsible User' in the UI. Kaggle admin responsible for the + competition. Only used for logging purposes. """ def __init__(self): @@ -116,6 +128,9 @@ def __init__(self): self._max_cpu_runtime_minutes = None self._max_gpu_runtime_minutes = None self._rerun_override_kernel_id = None + self._gateway_kernel_id = None + self._rerun_max_stagger_minutes = 0.0 + self._directly_responsible_user_id = None self._freeze() @property @@ -522,6 +537,60 @@ def rerun_override_kernel_id(self, rerun_override_kernel_id: Optional[int]): raise TypeError('rerun_override_kernel_id must be of type int') self._rerun_override_kernel_id = rerun_override_kernel_id + @property + def gateway_kernel_id(self) -> int: + r""" + 'Gateway Kernel Id' in the UI. Identifies the notebook whose latest + version is used as the source for the parent (gateway) container in + go/project-hearth rerun sessions. + """ + return self._gateway_kernel_id or 0 + + @gateway_kernel_id.setter + def gateway_kernel_id(self, gateway_kernel_id: Optional[int]): + if gateway_kernel_id is None: + del self.gateway_kernel_id + return + if not isinstance(gateway_kernel_id, int): + raise TypeError('gateway_kernel_id must be of type int') + self._gateway_kernel_id = gateway_kernel_id + + @property + def rerun_max_stagger_minutes(self) -> float: + r""" + 'Rerun Max Stagger Minutes' in the UI. Random delay added before a + scoring run kicks off (sampled from 0..this value, clamped to 60). Used + for sync-rerun / Hearth competitions to limit private dataset probing. + """ + return self._rerun_max_stagger_minutes + + @rerun_max_stagger_minutes.setter + def rerun_max_stagger_minutes(self, rerun_max_stagger_minutes: float): + if rerun_max_stagger_minutes is None: + del self.rerun_max_stagger_minutes + return + if not isinstance(rerun_max_stagger_minutes, float): + raise TypeError('rerun_max_stagger_minutes must be of type float') + self._rerun_max_stagger_minutes = rerun_max_stagger_minutes + + @property + def directly_responsible_user_id(self) -> int: + r""" + HOSTS SETTINGS GROUP: ADMIN ONLY (field numbers 120-139) + 'Directly Responsible User' in the UI. Kaggle admin responsible for the + competition. Only used for logging purposes. + """ + return self._directly_responsible_user_id or 0 + + @directly_responsible_user_id.setter + def directly_responsible_user_id(self, directly_responsible_user_id: Optional[int]): + if directly_responsible_user_id is None: + del self.directly_responsible_user_id + return + if not isinstance(directly_responsible_user_id, int): + raise TypeError('directly_responsible_user_id must be of type int') + self._directly_responsible_user_id = directly_responsible_user_id + CompetitionSettings._fields = [ FieldMetadata("title", "title", "_title", str, "", PredefinedSerializer()), @@ -550,5 +619,8 @@ def rerun_override_kernel_id(self, rerun_override_kernel_id: Optional[int]): FieldMetadata("maxCpuRuntimeMinutes", "max_cpu_runtime_minutes", "_max_cpu_runtime_minutes", int, None, PredefinedSerializer(), optional=True), FieldMetadata("maxGpuRuntimeMinutes", "max_gpu_runtime_minutes", "_max_gpu_runtime_minutes", int, None, PredefinedSerializer(), optional=True), FieldMetadata("rerunOverrideKernelId", "rerun_override_kernel_id", "_rerun_override_kernel_id", int, None, PredefinedSerializer(), optional=True), + FieldMetadata("gatewayKernelId", "gateway_kernel_id", "_gateway_kernel_id", int, None, PredefinedSerializer(), optional=True), + FieldMetadata("rerunMaxStaggerMinutes", "rerun_max_stagger_minutes", "_rerun_max_stagger_minutes", float, 0.0, PredefinedSerializer()), + FieldMetadata("directlyResponsibleUserId", "directly_responsible_user_id", "_directly_responsible_user_id", int, None, PredefinedSerializer(), optional=True), ]