diff --git a/kagglesdk/__init__.py b/kagglesdk/__init__.py index 2d803b4..1caae2c 100644 --- a/kagglesdk/__init__.py +++ b/kagglesdk/__init__.py @@ -1,4 +1,4 @@ -__version__ = "0.1.16" +__version__ = "0.1.17" from kagglesdk.kaggle_client import KaggleClient from kagglesdk.kaggle_creds import KaggleCredentials diff --git a/kagglesdk/abuse/__init__.py b/kagglesdk/abuse/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/kagglesdk/abuse/types/__init__.py b/kagglesdk/abuse/types/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/kagglesdk/abuse/types/abuse_enums.py b/kagglesdk/abuse/types/abuse_enums.py new file mode 100644 index 0000000..8a44a2c --- /dev/null +++ b/kagglesdk/abuse/types/abuse_enums.py @@ -0,0 +1,7 @@ +import enum + +class PrivatedModerationStatus(enum.Enum): + PRIVATED_MODERATION_STATUS_UNSPECIFIED = 0 + PRIVATED_MODERATION_STATUS_NO_ABUSE = 1 + PERMANENTLY_PRIVATED = 3 + diff --git a/kagglesdk/agents/__init__.py b/kagglesdk/agents/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/kagglesdk/agents/services/__init__.py b/kagglesdk/agents/services/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/kagglesdk/agents/services/agent_exam_service.py b/kagglesdk/agents/services/agent_exam_service.py new file mode 100644 index 0000000..43c78ca --- /dev/null +++ b/kagglesdk/agents/services/agent_exam_service.py @@ -0,0 +1,91 @@ +from kagglesdk.agents.types.agent_exam_service import ApiCompleteAgentExamSubmissionRequest, ApiCompleteAgentExamSubmissionResponse, ApiCreateAgentExamAgentRequest, ApiCreateAgentExamAgentResponse, ApiCreateAgentExamSubmissionRequest, ApiCreateAgentExamSubmissionResponse, ApiGetAgentExamAgentRequest, ApiGetAgentExamAgentResponse, ApiGetAgentExamInsightsRequest, ApiGetAgentExamInsightsResponse, ApiGetAgentExamSubmissionRequest, ApiGetAgentExamSubmissionResponse, ApiListTopAgentExamAgentsRequest, ApiListTopAgentExamAgentsResponse +from kagglesdk.kaggle_http_client import KaggleHttpClient + +class AgentExamClient(object): + + def __init__(self, client: KaggleHttpClient): + self._client = client + + def create_agent_exam_agent(self, request: ApiCreateAgentExamAgentRequest = None) -> ApiCreateAgentExamAgentResponse: + r""" + Args: + request (ApiCreateAgentExamAgentRequest): + The request object; initialized to empty instance if not specified. + """ + + if request is None: + request = ApiCreateAgentExamAgentRequest() + + return self._client.call("agents.AgentExamService", "CreateAgentExamAgent", request, ApiCreateAgentExamAgentResponse) + + def get_agent_exam_agent(self, request: ApiGetAgentExamAgentRequest = None) -> ApiGetAgentExamAgentResponse: + r""" + Args: + request (ApiGetAgentExamAgentRequest): + The request object; initialized to empty instance if not specified. + """ + + if request is None: + request = ApiGetAgentExamAgentRequest() + + return self._client.call("agents.AgentExamService", "GetAgentExamAgent", request, ApiGetAgentExamAgentResponse) + + def create_agent_exam_submission(self, request: ApiCreateAgentExamSubmissionRequest = None) -> ApiCreateAgentExamSubmissionResponse: + r""" + Args: + request (ApiCreateAgentExamSubmissionRequest): + The request object; initialized to empty instance if not specified. + """ + + if request is None: + request = ApiCreateAgentExamSubmissionRequest() + + return self._client.call("agents.AgentExamService", "CreateAgentExamSubmission", request, ApiCreateAgentExamSubmissionResponse) + + def complete_agent_exam_submission(self, request: ApiCompleteAgentExamSubmissionRequest = None) -> ApiCompleteAgentExamSubmissionResponse: + r""" + Args: + request (ApiCompleteAgentExamSubmissionRequest): + The request object; initialized to empty instance if not specified. + """ + + if request is None: + request = ApiCompleteAgentExamSubmissionRequest() + + return self._client.call("agents.AgentExamService", "CompleteAgentExamSubmission", request, ApiCompleteAgentExamSubmissionResponse) + + def get_agent_exam_submission(self, request: ApiGetAgentExamSubmissionRequest = None) -> ApiGetAgentExamSubmissionResponse: + r""" + Args: + request (ApiGetAgentExamSubmissionRequest): + The request object; initialized to empty instance if not specified. + """ + + if request is None: + request = ApiGetAgentExamSubmissionRequest() + + return self._client.call("agents.AgentExamService", "GetAgentExamSubmission", request, ApiGetAgentExamSubmissionResponse) + + def list_top_agent_exam_agents(self, request: ApiListTopAgentExamAgentsRequest = None) -> ApiListTopAgentExamAgentsResponse: + r""" + Args: + request (ApiListTopAgentExamAgentsRequest): + The request object; initialized to empty instance if not specified. + """ + + if request is None: + request = ApiListTopAgentExamAgentsRequest() + + return self._client.call("agents.AgentExamService", "ListTopAgentExamAgents", request, ApiListTopAgentExamAgentsResponse) + + def get_agent_exam_insights(self, request: ApiGetAgentExamInsightsRequest = None) -> ApiGetAgentExamInsightsResponse: + r""" + Args: + request (ApiGetAgentExamInsightsRequest): + The request object; initialized to empty instance if not specified. + """ + + if request is None: + request = ApiGetAgentExamInsightsRequest() + + return self._client.call("agents.AgentExamService", "GetAgentExamInsights", request, ApiGetAgentExamInsightsResponse) diff --git a/kagglesdk/agents/types/__init__.py b/kagglesdk/agents/types/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/kagglesdk/agents/types/agent_exam_enums.py b/kagglesdk/agents/types/agent_exam_enums.py new file mode 100644 index 0000000..20f3afc --- /dev/null +++ b/kagglesdk/agents/types/agent_exam_enums.py @@ -0,0 +1,9 @@ +import enum + +class AgentExamSubmissionStatus(enum.Enum): + """Saved to the DB. Do not modify existing values.""" + AGENT_EXAM_SUBMISSION_STATUS_UNSPECIFIED = 0 + AGENT_EXAM_SUBMISSION_STATUS_STARTED = 1 + AGENT_EXAM_SUBMISSION_STATUS_COMPLETED = 2 + AGENT_EXAM_SUBMISSION_STATUS_TIMED_OUT = 3 + diff --git a/kagglesdk/agents/types/agent_exam_service.py b/kagglesdk/agents/types/agent_exam_service.py new file mode 100644 index 0000000..7f83f41 --- /dev/null +++ b/kagglesdk/agents/types/agent_exam_service.py @@ -0,0 +1,1535 @@ +from kagglesdk.agents.types.agent_exam_enums import AgentExamSubmissionStatus +from kagglesdk.kaggle_object import * +from typing import Dict, Optional, List + +class AgentExamAgentScore(KaggleObject): + r""" + Attributes: + agent_id (str) + agent_name (str) + model (str) + best_score (int) + total_exams (int) + agent_type (str) + description (str) + """ + + def __init__(self): + self._agent_id = "" + self._agent_name = "" + self._model = "" + self._best_score = 0 + self._total_exams = 0 + self._agent_type = None + self._description = None + self._freeze() + + @property + def agent_id(self) -> str: + return self._agent_id + + @agent_id.setter + def agent_id(self, agent_id: str): + if agent_id is None: + del self.agent_id + return + if not isinstance(agent_id, str): + raise TypeError('agent_id must be of type str') + self._agent_id = agent_id + + @property + def agent_name(self) -> str: + return self._agent_name + + @agent_name.setter + def agent_name(self, agent_name: str): + if agent_name is None: + del self.agent_name + return + if not isinstance(agent_name, str): + raise TypeError('agent_name must be of type str') + self._agent_name = agent_name + + @property + def model(self) -> str: + return self._model + + @model.setter + def model(self, model: str): + if model is None: + del self.model + return + if not isinstance(model, str): + raise TypeError('model must be of type str') + self._model = model + + @property + def best_score(self) -> int: + return self._best_score + + @best_score.setter + def best_score(self, best_score: int): + if best_score is None: + del self.best_score + return + if not isinstance(best_score, int): + raise TypeError('best_score must be of type int') + self._best_score = best_score + + @property + def total_exams(self) -> int: + return self._total_exams + + @total_exams.setter + def total_exams(self, total_exams: int): + if total_exams is None: + del self.total_exams + return + if not isinstance(total_exams, int): + raise TypeError('total_exams must be of type int') + self._total_exams = total_exams + + @property + def agent_type(self) -> str: + return self._agent_type or "" + + @agent_type.setter + def agent_type(self, agent_type: Optional[str]): + if agent_type is None: + del self.agent_type + return + if not isinstance(agent_type, str): + raise TypeError('agent_type must be of type str') + self._agent_type = agent_type + + @property + def description(self) -> str: + 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 + + +class AgentExamQuestion(KaggleObject): + r""" + Attributes: + id (str) + text (str) + options (str) + """ + + def __init__(self): + self._id = "" + self._text = "" + self._options = [] + self._freeze() + + @property + def id(self) -> str: + return self._id + + @id.setter + def id(self, id: str): + if id is None: + del self.id + return + if not isinstance(id, str): + raise TypeError('id must be of type str') + self._id = id + + @property + def text(self) -> str: + return self._text + + @text.setter + def text(self, text: str): + if text is None: + del self.text + return + if not isinstance(text, str): + raise TypeError('text must be of type str') + self._text = text + + @property + def options(self) -> Optional[List[str]]: + return self._options + + @options.setter + def options(self, options: Optional[List[str]]): + if options is None: + del self.options + return + if not isinstance(options, list): + raise TypeError('options must be of type list') + if not all([isinstance(t, str) for t in options]): + raise TypeError('options must contain only items of type str') + self._options = options + + +class AgentExamSubmissionSummary(KaggleObject): + r""" + Attributes: + submission_id (str) + status (AgentExamSubmissionStatus) + score (int) + max_score (int) + percentage (float) + passed (bool) + started_at (str) + submitted_at (str) + """ + + def __init__(self): + self._submission_id = "" + self._status = AgentExamSubmissionStatus.AGENT_EXAM_SUBMISSION_STATUS_UNSPECIFIED + self._score = None + self._max_score = None + self._percentage = None + self._passed = None + self._started_at = "" + self._submitted_at = None + self._freeze() + + @property + def submission_id(self) -> str: + return self._submission_id + + @submission_id.setter + def submission_id(self, submission_id: str): + if submission_id is None: + del self.submission_id + return + if not isinstance(submission_id, str): + raise TypeError('submission_id must be of type str') + self._submission_id = submission_id + + @property + def status(self) -> 'AgentExamSubmissionStatus': + return self._status + + @status.setter + def status(self, status: 'AgentExamSubmissionStatus'): + if status is None: + del self.status + return + if not isinstance(status, AgentExamSubmissionStatus): + raise TypeError('status must be of type AgentExamSubmissionStatus') + self._status = status + + @property + def score(self) -> int: + return self._score or 0 + + @score.setter + def score(self, score: Optional[int]): + if score is None: + del self.score + return + if not isinstance(score, int): + raise TypeError('score must be of type int') + self._score = score + + @property + def max_score(self) -> int: + return self._max_score or 0 + + @max_score.setter + def max_score(self, max_score: Optional[int]): + if max_score is None: + del self.max_score + return + if not isinstance(max_score, int): + raise TypeError('max_score must be of type int') + self._max_score = max_score + + @property + def percentage(self) -> float: + return self._percentage or 0.0 + + @percentage.setter + def percentage(self, percentage: Optional[float]): + if percentage is None: + del self.percentage + return + if not isinstance(percentage, float): + raise TypeError('percentage must be of type float') + self._percentage = percentage + + @property + def passed(self) -> bool: + return self._passed or False + + @passed.setter + def passed(self, passed: Optional[bool]): + if passed is None: + del self.passed + return + if not isinstance(passed, bool): + raise TypeError('passed must be of type bool') + self._passed = passed + + @property + def started_at(self) -> str: + return self._started_at + + @started_at.setter + def started_at(self, started_at: str): + if started_at is None: + del self.started_at + return + if not isinstance(started_at, str): + raise TypeError('started_at must be of type str') + self._started_at = started_at + + @property + def submitted_at(self) -> str: + return self._submitted_at or "" + + @submitted_at.setter + def submitted_at(self, submitted_at: Optional[str]): + if submitted_at is None: + del self.submitted_at + return + if not isinstance(submitted_at, str): + raise TypeError('submitted_at must be of type str') + self._submitted_at = submitted_at + + +class ApiCompleteAgentExamSubmissionRequest(KaggleObject): + r""" + Attributes: + submission_id (str) + answers (str) + """ + + def __init__(self): + self._submission_id = "" + self._answers = {} + self._freeze() + + @property + def submission_id(self) -> str: + return self._submission_id + + @submission_id.setter + def submission_id(self, submission_id: str): + if submission_id is None: + del self.submission_id + return + if not isinstance(submission_id, str): + raise TypeError('submission_id must be of type str') + self._submission_id = submission_id + + @property + def answers(self) -> Optional[Dict[str, str]]: + return self._answers + + @answers.setter + def answers(self, answers: Optional[Dict[str, str]]): + if answers is None: + del self.answers + return + if not isinstance(answers, dict): + raise TypeError('answers must be of type dict') + if not all([isinstance(v, str) for k, v in answers]): + raise TypeError('answers must contain only items of type str') + self._answers = answers + + def endpoint(self): + path = '/api/v1/agentExamSubmission/{submission_id}' + return path.format_map(self.to_field_map(self)) + + + @staticmethod + def method(): + return 'POST' + + @staticmethod + def body_fields(): + return '*' + + +class ApiCompleteAgentExamSubmissionResponse(KaggleObject): + r""" + Attributes: + submission_id (str) + status (AgentExamSubmissionStatus) + score (int) + max_score (int) + percentage (float) + passed (bool) + certificate_id (str) + started_at (str) + submitted_at (str) + """ + + def __init__(self): + self._submission_id = "" + self._status = AgentExamSubmissionStatus.AGENT_EXAM_SUBMISSION_STATUS_UNSPECIFIED + self._score = 0 + self._max_score = 0 + self._percentage = 0.0 + self._passed = False + self._certificate_id = None + self._started_at = "" + self._submitted_at = "" + self._freeze() + + @property + def submission_id(self) -> str: + return self._submission_id + + @submission_id.setter + def submission_id(self, submission_id: str): + if submission_id is None: + del self.submission_id + return + if not isinstance(submission_id, str): + raise TypeError('submission_id must be of type str') + self._submission_id = submission_id + + @property + def status(self) -> 'AgentExamSubmissionStatus': + return self._status + + @status.setter + def status(self, status: 'AgentExamSubmissionStatus'): + if status is None: + del self.status + return + if not isinstance(status, AgentExamSubmissionStatus): + raise TypeError('status must be of type AgentExamSubmissionStatus') + self._status = status + + @property + def score(self) -> int: + return self._score + + @score.setter + def score(self, score: int): + if score is None: + del self.score + return + if not isinstance(score, int): + raise TypeError('score must be of type int') + self._score = score + + @property + def max_score(self) -> int: + return self._max_score + + @max_score.setter + def max_score(self, max_score: int): + if max_score is None: + del self.max_score + return + if not isinstance(max_score, int): + raise TypeError('max_score must be of type int') + self._max_score = max_score + + @property + def percentage(self) -> float: + return self._percentage + + @percentage.setter + def percentage(self, percentage: float): + if percentage is None: + del self.percentage + return + if not isinstance(percentage, float): + raise TypeError('percentage must be of type float') + self._percentage = percentage + + @property + def passed(self) -> bool: + return self._passed + + @passed.setter + def passed(self, passed: bool): + if passed is None: + del self.passed + return + if not isinstance(passed, bool): + raise TypeError('passed must be of type bool') + self._passed = passed + + @property + def certificate_id(self) -> str: + return self._certificate_id or "" + + @certificate_id.setter + def certificate_id(self, certificate_id: Optional[str]): + if certificate_id is None: + del self.certificate_id + return + if not isinstance(certificate_id, str): + raise TypeError('certificate_id must be of type str') + self._certificate_id = certificate_id + + @property + def started_at(self) -> str: + return self._started_at + + @started_at.setter + def started_at(self, started_at: str): + if started_at is None: + del self.started_at + return + if not isinstance(started_at, str): + raise TypeError('started_at must be of type str') + self._started_at = started_at + + @property + def submitted_at(self) -> str: + return self._submitted_at + + @submitted_at.setter + def submitted_at(self, submitted_at: str): + if submitted_at is None: + del self.submitted_at + return + if not isinstance(submitted_at, str): + raise TypeError('submitted_at must be of type str') + self._submitted_at = submitted_at + + @property + def submissionId(self): + return self.submission_id + + @property + def maxScore(self): + return self.max_score + + @property + def certificateId(self): + return self.certificate_id + + @property + def startedAt(self): + return self.started_at + + @property + def submittedAt(self): + return self.submitted_at + + +class ApiCreateAgentExamAgentRequest(KaggleObject): + r""" + Attributes: + name (str) + model (str) + version (str) + description (str) + agent_type (str) + """ + + def __init__(self): + self._name = "" + self._model = "" + self._version = "" + self._description = None + self._agent_type = None + 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 model(self) -> str: + return self._model + + @model.setter + def model(self, model: str): + if model is None: + del self.model + return + if not isinstance(model, str): + raise TypeError('model must be of type str') + self._model = model + + @property + def version(self) -> str: + return self._version + + @version.setter + def version(self, version: str): + if version is None: + del self.version + return + if not isinstance(version, str): + raise TypeError('version must be of type str') + self._version = version + + @property + def description(self) -> str: + 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 agent_type(self) -> str: + return self._agent_type or "" + + @agent_type.setter + def agent_type(self, agent_type: Optional[str]): + if agent_type is None: + del self.agent_type + return + if not isinstance(agent_type, str): + raise TypeError('agent_type must be of type str') + self._agent_type = agent_type + + def endpoint(self): + path = '/api/v1/agentExamAgent' + return path.format_map(self.to_field_map(self)) + + + @staticmethod + def method(): + return 'POST' + + @staticmethod + def body_fields(): + return '*' + + +class ApiCreateAgentExamAgentResponse(KaggleObject): + r""" + Attributes: + agent_id (str) + api_token (str) + description (str) + agent_type (str) + """ + + def __init__(self): + self._agent_id = "" + self._api_token = "" + self._description = None + self._agent_type = None + self._freeze() + + @property + def agent_id(self) -> str: + return self._agent_id + + @agent_id.setter + def agent_id(self, agent_id: str): + if agent_id is None: + del self.agent_id + return + if not isinstance(agent_id, str): + raise TypeError('agent_id must be of type str') + self._agent_id = agent_id + + @property + def api_token(self) -> str: + return self._api_token + + @api_token.setter + def api_token(self, api_token: str): + if api_token is None: + del self.api_token + return + if not isinstance(api_token, str): + raise TypeError('api_token must be of type str') + self._api_token = api_token + + @property + def description(self) -> str: + 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 agent_type(self) -> str: + return self._agent_type or "" + + @agent_type.setter + def agent_type(self, agent_type: Optional[str]): + if agent_type is None: + del self.agent_type + return + if not isinstance(agent_type, str): + raise TypeError('agent_type must be of type str') + self._agent_type = agent_type + + @property + def agentId(self): + return self.agent_id + + @property + def apiToken(self): + return self.api_token + + @property + def agentType(self): + return self.agent_type + + +class ApiCreateAgentExamSubmissionRequest(KaggleObject): + r""" + """ + + pass + def endpoint(self): + path = '/api/v1/agentExamSubmission' + return path.format_map(self.to_field_map(self)) + + + @staticmethod + def method(): + return 'POST' + + @staticmethod + def body_fields(): + return '*' + + +class ApiCreateAgentExamSubmissionResponse(KaggleObject): + r""" + Attributes: + submission_id (str) + status (AgentExamSubmissionStatus) + started_at (str) + time_limit_minutes (int) + questions (AgentExamQuestion) + """ + + def __init__(self): + self._submission_id = "" + self._status = AgentExamSubmissionStatus.AGENT_EXAM_SUBMISSION_STATUS_UNSPECIFIED + self._started_at = "" + self._time_limit_minutes = 0 + self._questions = [] + self._freeze() + + @property + def submission_id(self) -> str: + return self._submission_id + + @submission_id.setter + def submission_id(self, submission_id: str): + if submission_id is None: + del self.submission_id + return + if not isinstance(submission_id, str): + raise TypeError('submission_id must be of type str') + self._submission_id = submission_id + + @property + def status(self) -> 'AgentExamSubmissionStatus': + return self._status + + @status.setter + def status(self, status: 'AgentExamSubmissionStatus'): + if status is None: + del self.status + return + if not isinstance(status, AgentExamSubmissionStatus): + raise TypeError('status must be of type AgentExamSubmissionStatus') + self._status = status + + @property + def started_at(self) -> str: + return self._started_at + + @started_at.setter + def started_at(self, started_at: str): + if started_at is None: + del self.started_at + return + if not isinstance(started_at, str): + raise TypeError('started_at must be of type str') + self._started_at = started_at + + @property + def time_limit_minutes(self) -> int: + return self._time_limit_minutes + + @time_limit_minutes.setter + def time_limit_minutes(self, time_limit_minutes: int): + if time_limit_minutes is None: + del self.time_limit_minutes + return + if not isinstance(time_limit_minutes, int): + raise TypeError('time_limit_minutes must be of type int') + self._time_limit_minutes = time_limit_minutes + + @property + def questions(self) -> Optional[List[Optional['AgentExamQuestion']]]: + return self._questions + + @questions.setter + def questions(self, questions: Optional[List[Optional['AgentExamQuestion']]]): + if questions is None: + del self.questions + return + if not isinstance(questions, list): + raise TypeError('questions must be of type list') + if not all([isinstance(t, AgentExamQuestion) for t in questions]): + raise TypeError('questions must contain only items of type AgentExamQuestion') + self._questions = questions + + @property + def submissionId(self): + return self.submission_id + + @property + def startedAt(self): + return self.started_at + + @property + def timeLimitMinutes(self): + return self.time_limit_minutes + + +class ApiGetAgentExamAgentRequest(KaggleObject): + r""" + Attributes: + agent_id (str) + """ + + def __init__(self): + self._agent_id = "" + self._freeze() + + @property + def agent_id(self) -> str: + return self._agent_id + + @agent_id.setter + def agent_id(self, agent_id: str): + if agent_id is None: + del self.agent_id + return + if not isinstance(agent_id, str): + raise TypeError('agent_id must be of type str') + self._agent_id = agent_id + + def endpoint(self): + path = '/api/v1/agentExamAgent/{agent_id}' + return path.format_map(self.to_field_map(self)) + + @staticmethod + def endpoint_path(): + return '/api/v1/agentExamAgent/{agent_id}' + + +class ApiGetAgentExamAgentResponse(KaggleObject): + r""" + Attributes: + agent_id (str) + name (str) + model (str) + version (str) + registered_at (str) + submissions (AgentExamSubmissionSummary) + description (str) + agent_type (str) + """ + + def __init__(self): + self._agent_id = "" + self._name = "" + self._model = "" + self._version = "" + self._registered_at = "" + self._submissions = [] + self._description = None + self._agent_type = None + self._freeze() + + @property + def agent_id(self) -> str: + return self._agent_id + + @agent_id.setter + def agent_id(self, agent_id: str): + if agent_id is None: + del self.agent_id + return + if not isinstance(agent_id, str): + raise TypeError('agent_id must be of type str') + self._agent_id = agent_id + + @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 model(self) -> str: + return self._model + + @model.setter + def model(self, model: str): + if model is None: + del self.model + return + if not isinstance(model, str): + raise TypeError('model must be of type str') + self._model = model + + @property + def version(self) -> str: + return self._version + + @version.setter + def version(self, version: str): + if version is None: + del self.version + return + if not isinstance(version, str): + raise TypeError('version must be of type str') + self._version = version + + @property + def registered_at(self) -> str: + return self._registered_at + + @registered_at.setter + def registered_at(self, registered_at: str): + if registered_at is None: + del self.registered_at + return + if not isinstance(registered_at, str): + raise TypeError('registered_at must be of type str') + self._registered_at = registered_at + + @property + def submissions(self) -> Optional[List[Optional['AgentExamSubmissionSummary']]]: + return self._submissions + + @submissions.setter + def submissions(self, submissions: Optional[List[Optional['AgentExamSubmissionSummary']]]): + if submissions is None: + del self.submissions + return + if not isinstance(submissions, list): + raise TypeError('submissions must be of type list') + if not all([isinstance(t, AgentExamSubmissionSummary) for t in submissions]): + raise TypeError('submissions must contain only items of type AgentExamSubmissionSummary') + self._submissions = submissions + + @property + def description(self) -> str: + 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 agent_type(self) -> str: + return self._agent_type or "" + + @agent_type.setter + def agent_type(self, agent_type: Optional[str]): + if agent_type is None: + del self.agent_type + return + if not isinstance(agent_type, str): + raise TypeError('agent_type must be of type str') + self._agent_type = agent_type + + @property + def agentId(self): + return self.agent_id + + @property + def registeredAt(self): + return self.registered_at + + @property + def agentType(self): + return self.agent_type + + +class ApiGetAgentExamInsightsRequest(KaggleObject): + r""" + """ + + pass + def endpoint(self): + path = '/api/v1/agentExam/Insights' + return path.format_map(self.to_field_map(self)) + + +class ApiGetAgentExamInsightsResponse(KaggleObject): + r""" + Attributes: + agents_registered (int) + total_submissions (int) + pct_completed (float) + score_distribution (ScoreDistributionBin) + agents_submitted (int) + """ + + def __init__(self): + self._agents_registered = 0 + self._total_submissions = 0 + self._pct_completed = 0.0 + self._score_distribution = [] + self._agents_submitted = 0 + self._freeze() + + @property + def agents_registered(self) -> int: + return self._agents_registered + + @agents_registered.setter + def agents_registered(self, agents_registered: int): + if agents_registered is None: + del self.agents_registered + return + if not isinstance(agents_registered, int): + raise TypeError('agents_registered must be of type int') + self._agents_registered = agents_registered + + @property + def total_submissions(self) -> int: + return self._total_submissions + + @total_submissions.setter + def total_submissions(self, total_submissions: int): + if total_submissions is None: + del self.total_submissions + return + if not isinstance(total_submissions, int): + raise TypeError('total_submissions must be of type int') + self._total_submissions = total_submissions + + @property + def pct_completed(self) -> float: + return self._pct_completed + + @pct_completed.setter + def pct_completed(self, pct_completed: float): + if pct_completed is None: + del self.pct_completed + return + if not isinstance(pct_completed, float): + raise TypeError('pct_completed must be of type float') + self._pct_completed = pct_completed + + @property + def score_distribution(self) -> Optional[List[Optional['ScoreDistributionBin']]]: + return self._score_distribution + + @score_distribution.setter + def score_distribution(self, score_distribution: Optional[List[Optional['ScoreDistributionBin']]]): + if score_distribution is None: + del self.score_distribution + return + if not isinstance(score_distribution, list): + raise TypeError('score_distribution must be of type list') + if not all([isinstance(t, ScoreDistributionBin) for t in score_distribution]): + raise TypeError('score_distribution must contain only items of type ScoreDistributionBin') + self._score_distribution = score_distribution + + @property + def agents_submitted(self) -> int: + return self._agents_submitted + + @agents_submitted.setter + def agents_submitted(self, agents_submitted: int): + if agents_submitted is None: + del self.agents_submitted + return + if not isinstance(agents_submitted, int): + raise TypeError('agents_submitted must be of type int') + self._agents_submitted = agents_submitted + + @property + def agentsRegistered(self): + return self.agents_registered + + @property + def totalSubmissions(self): + return self.total_submissions + + @property + def pctCompleted(self): + return self.pct_completed + + @property + def scoreDistribution(self): + return self.score_distribution + + @property + def agentsSubmitted(self): + return self.agents_submitted + + +class ApiGetAgentExamSubmissionRequest(KaggleObject): + r""" + Attributes: + submission_id (str) + """ + + def __init__(self): + self._submission_id = "" + self._freeze() + + @property + def submission_id(self) -> str: + return self._submission_id + + @submission_id.setter + def submission_id(self, submission_id: str): + if submission_id is None: + del self.submission_id + return + if not isinstance(submission_id, str): + raise TypeError('submission_id must be of type str') + self._submission_id = submission_id + + def endpoint(self): + path = '/api/v1/agentExamSubmission/{submission_id}' + return path.format_map(self.to_field_map(self)) + + @staticmethod + def endpoint_path(): + return '/api/v1/agentExamSubmission/{submission_id}' + + +class ApiGetAgentExamSubmissionResponse(KaggleObject): + r""" + Attributes: + submission_id (str) + status (AgentExamSubmissionStatus) + score (int) + max_score (int) + percentage (float) + passed (bool) + started_at (str) + submitted_at (str) + """ + + def __init__(self): + self._submission_id = "" + self._status = AgentExamSubmissionStatus.AGENT_EXAM_SUBMISSION_STATUS_UNSPECIFIED + self._score = None + self._max_score = None + self._percentage = None + self._passed = None + self._started_at = "" + self._submitted_at = None + self._freeze() + + @property + def submission_id(self) -> str: + return self._submission_id + + @submission_id.setter + def submission_id(self, submission_id: str): + if submission_id is None: + del self.submission_id + return + if not isinstance(submission_id, str): + raise TypeError('submission_id must be of type str') + self._submission_id = submission_id + + @property + def status(self) -> 'AgentExamSubmissionStatus': + return self._status + + @status.setter + def status(self, status: 'AgentExamSubmissionStatus'): + if status is None: + del self.status + return + if not isinstance(status, AgentExamSubmissionStatus): + raise TypeError('status must be of type AgentExamSubmissionStatus') + self._status = status + + @property + def score(self) -> int: + return self._score or 0 + + @score.setter + def score(self, score: Optional[int]): + if score is None: + del self.score + return + if not isinstance(score, int): + raise TypeError('score must be of type int') + self._score = score + + @property + def max_score(self) -> int: + return self._max_score or 0 + + @max_score.setter + def max_score(self, max_score: Optional[int]): + if max_score is None: + del self.max_score + return + if not isinstance(max_score, int): + raise TypeError('max_score must be of type int') + self._max_score = max_score + + @property + def percentage(self) -> float: + return self._percentage or 0.0 + + @percentage.setter + def percentage(self, percentage: Optional[float]): + if percentage is None: + del self.percentage + return + if not isinstance(percentage, float): + raise TypeError('percentage must be of type float') + self._percentage = percentage + + @property + def passed(self) -> bool: + return self._passed or False + + @passed.setter + def passed(self, passed: Optional[bool]): + if passed is None: + del self.passed + return + if not isinstance(passed, bool): + raise TypeError('passed must be of type bool') + self._passed = passed + + @property + def started_at(self) -> str: + return self._started_at + + @started_at.setter + def started_at(self, started_at: str): + if started_at is None: + del self.started_at + return + if not isinstance(started_at, str): + raise TypeError('started_at must be of type str') + self._started_at = started_at + + @property + def submitted_at(self) -> str: + return self._submitted_at or "" + + @submitted_at.setter + def submitted_at(self, submitted_at: Optional[str]): + if submitted_at is None: + del self.submitted_at + return + if not isinstance(submitted_at, str): + raise TypeError('submitted_at must be of type str') + self._submitted_at = submitted_at + + @property + def submissionId(self): + return self.submission_id + + @property + def maxScore(self): + return self.max_score + + @property + def startedAt(self): + return self.started_at + + @property + def submittedAt(self): + return self.submitted_at + + +class ApiListTopAgentExamAgentsRequest(KaggleObject): + r""" + Attributes: + page (int) + page_size (int) + """ + + def __init__(self): + self._page = 0 + self._page_size = 0 + self._freeze() + + @property + def page(self) -> int: + return self._page + + @page.setter + def page(self, page: int): + if page is None: + del self.page + return + if not isinstance(page, int): + raise TypeError('page must be of type int') + self._page = page + + @property + def page_size(self) -> int: + return self._page_size + + @page_size.setter + def page_size(self, page_size: int): + if page_size is None: + del self.page_size + return + if not isinstance(page_size, int): + raise TypeError('page_size must be of type int') + self._page_size = page_size + + def endpoint(self): + path = '/api/v1/agentExam/TopAgents' + return path.format_map(self.to_field_map(self)) + + +class ApiListTopAgentExamAgentsResponse(KaggleObject): + r""" + Attributes: + agents (AgentExamAgentScore) + total_count (int) + """ + + def __init__(self): + self._agents = [] + self._total_count = 0 + self._freeze() + + @property + def agents(self) -> Optional[List[Optional['AgentExamAgentScore']]]: + return self._agents + + @agents.setter + def agents(self, agents: Optional[List[Optional['AgentExamAgentScore']]]): + if agents is None: + del self.agents + return + if not isinstance(agents, list): + raise TypeError('agents must be of type list') + if not all([isinstance(t, AgentExamAgentScore) for t in agents]): + raise TypeError('agents must contain only items of type AgentExamAgentScore') + self._agents = agents + + @property + def total_count(self) -> int: + return self._total_count + + @total_count.setter + def total_count(self, total_count: int): + if total_count is None: + del self.total_count + return + if not isinstance(total_count, int): + raise TypeError('total_count must be of type int') + self._total_count = total_count + + @property + def totalCount(self): + return self.total_count + + +class ScoreDistributionBin(KaggleObject): + r""" + Attributes: + label (str) + count (int) + """ + + def __init__(self): + self._label = "" + self._count = 0 + self._freeze() + + @property + def label(self) -> str: + return self._label + + @label.setter + def label(self, label: str): + if label is None: + del self.label + return + if not isinstance(label, str): + raise TypeError('label must be of type str') + self._label = label + + @property + def count(self) -> int: + return self._count + + @count.setter + def count(self, count: int): + if count is None: + del self.count + return + if not isinstance(count, int): + raise TypeError('count must be of type int') + self._count = count + + +AgentExamAgentScore._fields = [ + FieldMetadata("agentId", "agent_id", "_agent_id", str, "", PredefinedSerializer()), + FieldMetadata("agentName", "agent_name", "_agent_name", str, "", PredefinedSerializer()), + FieldMetadata("model", "model", "_model", str, "", PredefinedSerializer()), + FieldMetadata("bestScore", "best_score", "_best_score", int, 0, PredefinedSerializer()), + FieldMetadata("totalExams", "total_exams", "_total_exams", int, 0, PredefinedSerializer()), + FieldMetadata("agentType", "agent_type", "_agent_type", str, None, PredefinedSerializer(), optional=True), + FieldMetadata("description", "description", "_description", str, None, PredefinedSerializer(), optional=True), +] + +AgentExamQuestion._fields = [ + FieldMetadata("id", "id", "_id", str, "", PredefinedSerializer()), + FieldMetadata("text", "text", "_text", str, "", PredefinedSerializer()), + FieldMetadata("options", "options", "_options", str, [], ListSerializer(PredefinedSerializer())), +] + +AgentExamSubmissionSummary._fields = [ + FieldMetadata("submissionId", "submission_id", "_submission_id", str, "", PredefinedSerializer()), + FieldMetadata("status", "status", "_status", AgentExamSubmissionStatus, AgentExamSubmissionStatus.AGENT_EXAM_SUBMISSION_STATUS_UNSPECIFIED, EnumSerializer()), + FieldMetadata("score", "score", "_score", int, None, PredefinedSerializer(), optional=True), + FieldMetadata("maxScore", "max_score", "_max_score", int, None, PredefinedSerializer(), optional=True), + FieldMetadata("percentage", "percentage", "_percentage", float, None, PredefinedSerializer(), optional=True), + FieldMetadata("passed", "passed", "_passed", bool, None, PredefinedSerializer(), optional=True), + FieldMetadata("startedAt", "started_at", "_started_at", str, "", PredefinedSerializer()), + FieldMetadata("submittedAt", "submitted_at", "_submitted_at", str, None, PredefinedSerializer(), optional=True), +] + +ApiCompleteAgentExamSubmissionRequest._fields = [ + FieldMetadata("submissionId", "submission_id", "_submission_id", str, "", PredefinedSerializer()), + FieldMetadata("answers", "answers", "_answers", str, {}, MapSerializer(PredefinedSerializer())), +] + +ApiCompleteAgentExamSubmissionResponse._fields = [ + FieldMetadata("submissionId", "submission_id", "_submission_id", str, "", PredefinedSerializer()), + FieldMetadata("status", "status", "_status", AgentExamSubmissionStatus, AgentExamSubmissionStatus.AGENT_EXAM_SUBMISSION_STATUS_UNSPECIFIED, EnumSerializer()), + FieldMetadata("score", "score", "_score", int, 0, PredefinedSerializer()), + FieldMetadata("maxScore", "max_score", "_max_score", int, 0, PredefinedSerializer()), + FieldMetadata("percentage", "percentage", "_percentage", float, 0.0, PredefinedSerializer()), + FieldMetadata("passed", "passed", "_passed", bool, False, PredefinedSerializer()), + FieldMetadata("certificateId", "certificate_id", "_certificate_id", str, None, PredefinedSerializer(), optional=True), + FieldMetadata("startedAt", "started_at", "_started_at", str, "", PredefinedSerializer()), + FieldMetadata("submittedAt", "submitted_at", "_submitted_at", str, "", PredefinedSerializer()), +] + +ApiCreateAgentExamAgentRequest._fields = [ + FieldMetadata("name", "name", "_name", str, "", PredefinedSerializer()), + FieldMetadata("model", "model", "_model", str, "", PredefinedSerializer()), + FieldMetadata("version", "version", "_version", str, "", PredefinedSerializer()), + FieldMetadata("description", "description", "_description", str, None, PredefinedSerializer(), optional=True), + FieldMetadata("agentType", "agent_type", "_agent_type", str, None, PredefinedSerializer(), optional=True), +] + +ApiCreateAgentExamAgentResponse._fields = [ + FieldMetadata("agentId", "agent_id", "_agent_id", str, "", PredefinedSerializer()), + FieldMetadata("apiToken", "api_token", "_api_token", str, "", PredefinedSerializer()), + FieldMetadata("description", "description", "_description", str, None, PredefinedSerializer(), optional=True), + FieldMetadata("agentType", "agent_type", "_agent_type", str, None, PredefinedSerializer(), optional=True), +] + +ApiCreateAgentExamSubmissionRequest._fields = [] + +ApiCreateAgentExamSubmissionResponse._fields = [ + FieldMetadata("submissionId", "submission_id", "_submission_id", str, "", PredefinedSerializer()), + FieldMetadata("status", "status", "_status", AgentExamSubmissionStatus, AgentExamSubmissionStatus.AGENT_EXAM_SUBMISSION_STATUS_UNSPECIFIED, EnumSerializer()), + FieldMetadata("startedAt", "started_at", "_started_at", str, "", PredefinedSerializer()), + FieldMetadata("timeLimitMinutes", "time_limit_minutes", "_time_limit_minutes", int, 0, PredefinedSerializer()), + FieldMetadata("questions", "questions", "_questions", AgentExamQuestion, [], ListSerializer(KaggleObjectSerializer())), +] + +ApiGetAgentExamAgentRequest._fields = [ + FieldMetadata("agentId", "agent_id", "_agent_id", str, "", PredefinedSerializer()), +] + +ApiGetAgentExamAgentResponse._fields = [ + FieldMetadata("agentId", "agent_id", "_agent_id", str, "", PredefinedSerializer()), + FieldMetadata("name", "name", "_name", str, "", PredefinedSerializer()), + FieldMetadata("model", "model", "_model", str, "", PredefinedSerializer()), + FieldMetadata("version", "version", "_version", str, "", PredefinedSerializer()), + FieldMetadata("registeredAt", "registered_at", "_registered_at", str, "", PredefinedSerializer()), + FieldMetadata("submissions", "submissions", "_submissions", AgentExamSubmissionSummary, [], ListSerializer(KaggleObjectSerializer())), + FieldMetadata("description", "description", "_description", str, None, PredefinedSerializer(), optional=True), + FieldMetadata("agentType", "agent_type", "_agent_type", str, None, PredefinedSerializer(), optional=True), +] + +ApiGetAgentExamInsightsRequest._fields = [] + +ApiGetAgentExamInsightsResponse._fields = [ + FieldMetadata("agentsRegistered", "agents_registered", "_agents_registered", int, 0, PredefinedSerializer()), + FieldMetadata("totalSubmissions", "total_submissions", "_total_submissions", int, 0, PredefinedSerializer()), + FieldMetadata("pctCompleted", "pct_completed", "_pct_completed", float, 0.0, PredefinedSerializer()), + FieldMetadata("scoreDistribution", "score_distribution", "_score_distribution", ScoreDistributionBin, [], ListSerializer(KaggleObjectSerializer())), + FieldMetadata("agentsSubmitted", "agents_submitted", "_agents_submitted", int, 0, PredefinedSerializer()), +] + +ApiGetAgentExamSubmissionRequest._fields = [ + FieldMetadata("submissionId", "submission_id", "_submission_id", str, "", PredefinedSerializer()), +] + +ApiGetAgentExamSubmissionResponse._fields = [ + FieldMetadata("submissionId", "submission_id", "_submission_id", str, "", PredefinedSerializer()), + FieldMetadata("status", "status", "_status", AgentExamSubmissionStatus, AgentExamSubmissionStatus.AGENT_EXAM_SUBMISSION_STATUS_UNSPECIFIED, EnumSerializer()), + FieldMetadata("score", "score", "_score", int, None, PredefinedSerializer(), optional=True), + FieldMetadata("maxScore", "max_score", "_max_score", int, None, PredefinedSerializer(), optional=True), + FieldMetadata("percentage", "percentage", "_percentage", float, None, PredefinedSerializer(), optional=True), + FieldMetadata("passed", "passed", "_passed", bool, None, PredefinedSerializer(), optional=True), + FieldMetadata("startedAt", "started_at", "_started_at", str, "", PredefinedSerializer()), + FieldMetadata("submittedAt", "submitted_at", "_submitted_at", str, None, PredefinedSerializer(), optional=True), +] + +ApiListTopAgentExamAgentsRequest._fields = [ + FieldMetadata("page", "page", "_page", int, 0, PredefinedSerializer()), + FieldMetadata("pageSize", "page_size", "_page_size", int, 0, PredefinedSerializer()), +] + +ApiListTopAgentExamAgentsResponse._fields = [ + FieldMetadata("agents", "agents", "_agents", AgentExamAgentScore, [], ListSerializer(KaggleObjectSerializer())), + FieldMetadata("totalCount", "total_count", "_total_count", int, 0, PredefinedSerializer()), +] + +ScoreDistributionBin._fields = [ + FieldMetadata("label", "label", "_label", str, "", PredefinedSerializer()), + FieldMetadata("count", "count", "_count", int, 0, PredefinedSerializer()), +] + diff --git a/kagglesdk/benchmarks/services/benchmark_tasks_api_service.py b/kagglesdk/benchmarks/services/benchmark_tasks_api_service.py new file mode 100644 index 0000000..2a3562e --- /dev/null +++ b/kagglesdk/benchmarks/services/benchmark_tasks_api_service.py @@ -0,0 +1,108 @@ +from kagglesdk.benchmarks.types.benchmark_tasks_api_service import ApiBatchScheduleBenchmarkTaskRunsRequest, ApiBatchScheduleBenchmarkTaskRunsResponse, ApiBenchmarkTask, ApiCreateBenchmarkTaskRequest, ApiDownloadBenchmarkTaskRunOutputRequest, ApiGetBenchmarkTaskQuotaRequest, ApiGetBenchmarkTaskQuotaResponse, ApiGetBenchmarkTaskRequest, ApiListBenchmarkTaskRunsRequest, ApiListBenchmarkTaskRunsResponse, ApiListBenchmarkTasksRequest, ApiListBenchmarkTasksResponse +from kagglesdk.common.types.file_download import FileDownload +from kagglesdk.kaggle_http_client import KaggleHttpClient + +class BenchmarkTasksApiClient(object): + + def __init__(self, client: KaggleHttpClient): + self._client = client + + def create_benchmark_task(self, request: ApiCreateBenchmarkTaskRequest = None) -> ApiBenchmarkTask: + r""" + For the given slug: + * if it exists: creates a new task version (under the existing task) + * if it does not exist: creates a new task (and 1st task version) + + Args: + request (ApiCreateBenchmarkTaskRequest): + The request object; initialized to empty instance if not specified. + """ + + if request is None: + request = ApiCreateBenchmarkTaskRequest() + + return self._client.call("benchmarks.BenchmarkTasksApiService", "CreateBenchmarkTask", request, ApiBenchmarkTask) + + def batch_schedule_benchmark_task_runs(self, request: ApiBatchScheduleBenchmarkTaskRunsRequest = None) -> ApiBatchScheduleBenchmarkTaskRunsResponse: + r""" + Schedules runs for a set of tasks against a set of models. + + Args: + request (ApiBatchScheduleBenchmarkTaskRunsRequest): + The request object; initialized to empty instance if not specified. + """ + + if request is None: + request = ApiBatchScheduleBenchmarkTaskRunsRequest() + + return self._client.call("benchmarks.BenchmarkTasksApiService", "BatchScheduleBenchmarkTaskRuns", request, ApiBatchScheduleBenchmarkTaskRunsResponse) + + def list_benchmark_tasks(self, request: ApiListBenchmarkTasksRequest = None) -> ApiListBenchmarkTasksResponse: + r""" + List tasks for the current user. + + Args: + request (ApiListBenchmarkTasksRequest): + The request object; initialized to empty instance if not specified. + """ + + if request is None: + request = ApiListBenchmarkTasksRequest() + + return self._client.call("benchmarks.BenchmarkTasksApiService", "ListBenchmarkTasks", request, ApiListBenchmarkTasksResponse) + + def get_benchmark_task(self, request: ApiGetBenchmarkTaskRequest = None) -> ApiBenchmarkTask: + r""" + Get a particular task for a user. + + Args: + request (ApiGetBenchmarkTaskRequest): + The request object; initialized to empty instance if not specified. + """ + + if request is None: + request = ApiGetBenchmarkTaskRequest() + + return self._client.call("benchmarks.BenchmarkTasksApiService", "GetBenchmarkTask", request, ApiBenchmarkTask) + + def list_benchmark_task_runs(self, request: ApiListBenchmarkTaskRunsRequest = None) -> ApiListBenchmarkTaskRunsResponse: + r""" + List runs for a particular task. + + Args: + request (ApiListBenchmarkTaskRunsRequest): + The request object; initialized to empty instance if not specified. + """ + + if request is None: + request = ApiListBenchmarkTaskRunsRequest() + + return self._client.call("benchmarks.BenchmarkTasksApiService", "ListBenchmarkTaskRuns", request, ApiListBenchmarkTaskRunsResponse) + + def download_benchmark_task_run_output(self, request: ApiDownloadBenchmarkTaskRunOutputRequest = None) -> FileDownload: + r""" + Download output files for a completed task run. + + Args: + request (ApiDownloadBenchmarkTaskRunOutputRequest): + The request object; initialized to empty instance if not specified. + """ + + if request is None: + request = ApiDownloadBenchmarkTaskRunOutputRequest() + + return self._client.call("benchmarks.BenchmarkTasksApiService", "DownloadBenchmarkTaskRunOutput", request, FileDownload) + + def get_benchmark_task_quota(self, request: ApiGetBenchmarkTaskQuotaRequest = None) -> ApiGetBenchmarkTaskQuotaResponse: + r""" + Return the current user's model proxy quota. + + Args: + request (ApiGetBenchmarkTaskQuotaRequest): + The request object; initialized to empty instance if not specified. + """ + + if request is None: + request = ApiGetBenchmarkTaskQuotaRequest() + + return self._client.call("benchmarks.BenchmarkTasksApiService", "GetBenchmarkTaskQuota", request, ApiGetBenchmarkTaskQuotaResponse) diff --git a/kagglesdk/benchmarks/services/benchmarks_api_service.py b/kagglesdk/benchmarks/services/benchmarks_api_service.py index dacbb22..edab594 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, ApiGetBenchmarkLeaderboardRequest +from kagglesdk.benchmarks.types.benchmarks_api_service import ApiBenchmarkLeaderboard, ApiGetBenchmarkLeaderboardRequest, ApiListBenchmarkModelsRequest, ApiListBenchmarkModelsResponse from kagglesdk.kaggle_http_client import KaggleHttpClient class BenchmarksApiClient(object): @@ -17,3 +17,15 @@ def get_benchmark_leaderboard(self, request: ApiGetBenchmarkLeaderboardRequest = request = ApiGetBenchmarkLeaderboardRequest() return self._client.call("benchmarks.BenchmarksApiService", "GetBenchmarkLeaderboard", request, ApiBenchmarkLeaderboard) + + def list_benchmark_models(self, request: ApiListBenchmarkModelsRequest = None) -> ApiListBenchmarkModelsResponse: + r""" + Args: + request (ApiListBenchmarkModelsRequest): + The request object; initialized to empty instance if not specified. + """ + + if request is None: + request = ApiListBenchmarkModelsRequest() + + return self._client.call("benchmarks.BenchmarksApiService", "ListBenchmarkModels", request, ApiListBenchmarkModelsResponse) diff --git a/kagglesdk/benchmarks/types/benchmark_enums.py b/kagglesdk/benchmarks/types/benchmark_enums.py new file mode 100644 index 0000000..b7afde2 --- /dev/null +++ b/kagglesdk/benchmarks/types/benchmark_enums.py @@ -0,0 +1,30 @@ +import enum + +class BenchmarkModelImportanceLevel(enum.Enum): + r""" + Determines whether the model will be run on + Kaggle-maintained benchmarks + See http://goto.google.com/kaggle-benchmarks-model-coverage + """ + BENCHMARK_MODEL_IMPORTANCE_LEVEL_UNSPECIFIED = 0 + CORE = 1 + r""" + Model should be ran on + all Kaggle-maintained benchmarks + """ + +class BenchmarkTaskVersionCreationState(enum.Enum): + """Saved to the DB. Do not modify existing values.""" + BENCHMARK_TASK_VERSION_CREATION_STATE_UNSPECIFIED = 0 + BENCHMARK_TASK_VERSION_CREATION_STATE_QUEUED = 1 + BENCHMARK_TASK_VERSION_CREATION_STATE_RUNNING = 2 + BENCHMARK_TASK_VERSION_CREATION_STATE_COMPLETED = 3 + BENCHMARK_TASK_VERSION_CREATION_STATE_ERRORED = 4 + +class BenchmarkTaskRunState(enum.Enum): + BENCHMARK_TASK_RUN_STATE_UNSPECIFIED = 0 + BENCHMARK_TASK_RUN_STATE_QUEUED = 1 + BENCHMARK_TASK_RUN_STATE_RUNNING = 2 + BENCHMARK_TASK_RUN_STATE_COMPLETED = 3 + BENCHMARK_TASK_RUN_STATE_ERRORED = 4 + diff --git a/kagglesdk/benchmarks/types/benchmark_task_run_service.py b/kagglesdk/benchmarks/types/benchmark_task_run_service.py new file mode 100644 index 0000000..09c28dc --- /dev/null +++ b/kagglesdk/benchmarks/types/benchmark_task_run_service.py @@ -0,0 +1,103 @@ +from kagglesdk.kaggle_object import * +from typing import Optional + +class BatchScheduleBenchmarkModelVersionResult(KaggleObject): + r""" + Attributes: + benchmark_model_version_id (int) + One of the values provided in + BatchScheduleBenchmarkTaskRunsRequest.benchmark_model_versions + run_scheduled (bool) + Whether the run was scheduled for the provided (benchmark_task_version, + benchmark_model_version) pair + run_skipped_reason (str) + If run_scheduled was false, the reason the provided + (benchmark_task_version, benchmark_model_version) pair was skipped + benchmark_task_version_id (int) + One of the values provided in + BatchScheduleBenchmarkTaskRunsRequest.benchmark_task_versions + """ + + def __init__(self): + self._benchmark_model_version_id = 0 + self._run_scheduled = False + self._run_skipped_reason = None + self._benchmark_task_version_id = 0 + self._freeze() + + @property + def benchmark_task_version_id(self) -> int: + r""" + One of the values provided in + BatchScheduleBenchmarkTaskRunsRequest.benchmark_task_versions + """ + return self._benchmark_task_version_id + + @benchmark_task_version_id.setter + def benchmark_task_version_id(self, benchmark_task_version_id: int): + if benchmark_task_version_id is None: + del self.benchmark_task_version_id + return + if not isinstance(benchmark_task_version_id, int): + raise TypeError('benchmark_task_version_id must be of type int') + self._benchmark_task_version_id = benchmark_task_version_id + + @property + def benchmark_model_version_id(self) -> int: + r""" + One of the values provided in + BatchScheduleBenchmarkTaskRunsRequest.benchmark_model_versions + """ + return self._benchmark_model_version_id + + @benchmark_model_version_id.setter + def benchmark_model_version_id(self, benchmark_model_version_id: int): + if benchmark_model_version_id is None: + del self.benchmark_model_version_id + return + if not isinstance(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 run_scheduled(self) -> bool: + r""" + Whether the run was scheduled for the provided (benchmark_task_version, + benchmark_model_version) pair + """ + return self._run_scheduled + + @run_scheduled.setter + def run_scheduled(self, run_scheduled: bool): + if run_scheduled is None: + del self.run_scheduled + return + if not isinstance(run_scheduled, bool): + raise TypeError('run_scheduled must be of type bool') + self._run_scheduled = run_scheduled + + @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 + """ + return self._run_skipped_reason or "" + + @run_skipped_reason.setter + def run_skipped_reason(self, run_skipped_reason: Optional[str]): + if run_skipped_reason is None: + del self.run_skipped_reason + return + if not isinstance(run_skipped_reason, str): + raise TypeError('run_skipped_reason must be of type str') + self._run_skipped_reason = run_skipped_reason + + +BatchScheduleBenchmarkModelVersionResult._fields = [ + FieldMetadata("benchmarkModelVersionId", "benchmark_model_version_id", "_benchmark_model_version_id", int, 0, PredefinedSerializer()), + FieldMetadata("runScheduled", "run_scheduled", "_run_scheduled", bool, False, PredefinedSerializer()), + 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()), +] + diff --git a/kagglesdk/benchmarks/types/benchmark_tasks_api_service.py b/kagglesdk/benchmarks/types/benchmark_tasks_api_service.py new file mode 100644 index 0000000..7dbb9b3 --- /dev/null +++ b/kagglesdk/benchmarks/types/benchmark_tasks_api_service.py @@ -0,0 +1,793 @@ +from datetime import datetime +from kagglesdk.benchmarks.types.benchmark_enums import BenchmarkTaskRunState, BenchmarkTaskVersionCreationState +from kagglesdk.benchmarks.types.benchmark_task_run_service import BatchScheduleBenchmarkModelVersionResult +from kagglesdk.kaggle_object import * +from typing import List, Optional + +class ApiBatchScheduleBenchmarkTaskRunsRequest(KaggleObject): + r""" + Attributes: + task_slugs (ApiBenchmarkTaskSlug) + model_version_slugs (str) + """ + + def __init__(self): + self._task_slugs = [] + self._model_version_slugs = [] + self._freeze() + + @property + def task_slugs(self) -> Optional[List[Optional['ApiBenchmarkTaskSlug']]]: + 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 + + @property + def model_version_slugs(self) -> Optional[List[str]]: + return self._model_version_slugs + + @model_version_slugs.setter + def model_version_slugs(self, model_version_slugs: Optional[List[str]]): + if model_version_slugs is None: + del self.model_version_slugs + return + if not isinstance(model_version_slugs, list): + raise TypeError('model_version_slugs must be of type list') + if not all([isinstance(t, str) for t in model_version_slugs]): + raise TypeError('model_version_slugs must contain only items of type str') + self._model_version_slugs = model_version_slugs + + def endpoint(self): + path = '/api/v1/benchmarks/tasks/schedule' + return path.format_map(self.to_field_map(self)) + + + @staticmethod + def method(): + return 'POST' + + @staticmethod + def body_fields(): + return '*' + + +class ApiBatchScheduleBenchmarkTaskRunsResponse(KaggleObject): + r""" + Attributes: + results (BatchScheduleBenchmarkModelVersionResult) + """ + + def __init__(self): + self._results = [] + self._freeze() + + @property + def results(self) -> Optional[List[Optional['BatchScheduleBenchmarkModelVersionResult']]]: + return self._results + + @results.setter + def results(self, results: Optional[List[Optional['BatchScheduleBenchmarkModelVersionResult']]]): + if results is None: + del self.results + return + if not isinstance(results, list): + raise TypeError('results must be of type list') + if not all([isinstance(t, BatchScheduleBenchmarkModelVersionResult) for t in results]): + raise TypeError('results must contain only items of type BatchScheduleBenchmarkModelVersionResult') + self._results = results + + +class ApiBenchmarkTask(KaggleObject): + r""" + API equivalent of the BenchmarkTask + BenchmarkTaskVersion from + benchmark_types.proto. + + Attributes: + slug (ApiBenchmarkTaskSlug) + Identifier for the task (+version) + url (str) + URL to the created task (or new task version) + error (str) + Optional error string. + creation_state (BenchmarkTaskVersionCreationState) + Creation state, for now this is essentially the state of the first + underlying kernel session (SourceKernelSessionId). + create_time (datetime) + When this task version was created. + """ + + def __init__(self): + self._slug = None + self._url = "" + self._error = None + self._creation_state = BenchmarkTaskVersionCreationState.BENCHMARK_TASK_VERSION_CREATION_STATE_UNSPECIFIED + self._create_time = None + self._freeze() + + @property + def slug(self) -> Optional['ApiBenchmarkTaskSlug']: + """Identifier for the task (+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 url(self) -> str: + """URL to the created task (or new task version)""" + 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 + + @property + def error(self) -> str: + """Optional error string.""" + return self._error or "" + + @error.setter + def error(self, error: Optional[str]): + if error is None: + del self.error + return + if not isinstance(error, str): + raise TypeError('error must be of type str') + self._error = error + + @property + def creation_state(self) -> 'BenchmarkTaskVersionCreationState': + r""" + Creation state, for now this is essentially the state of the first + underlying kernel session (SourceKernelSessionId). + """ + return self._creation_state + + @creation_state.setter + def creation_state(self, creation_state: 'BenchmarkTaskVersionCreationState'): + if creation_state is None: + del self.creation_state + return + if not isinstance(creation_state, BenchmarkTaskVersionCreationState): + raise TypeError('creation_state must be of type BenchmarkTaskVersionCreationState') + self._creation_state = creation_state + + @property + def create_time(self) -> datetime: + """When this task version was created.""" + return self._create_time + + @create_time.setter + def create_time(self, create_time: datetime): + if create_time is None: + del self.create_time + return + if not isinstance(create_time, datetime): + raise TypeError('create_time must be of type datetime') + self._create_time = create_time + + +class ApiBenchmarkTaskRun(KaggleObject): + r""" + API equivalent of the BenchmarkTaskRun from benchmark_types.proto. + + Attributes: + task_slug (ApiBenchmarkTaskSlug) + Task that was invoked. + model_version_slug (str) + Model candidate against the task. + id (int) + Run identifier. + state (BenchmarkTaskRunState) + State of the run + start_time (datetime) + Start time of the run + end_time (datetime) + End time of the run + error_message (str) + Error message if the run failed + """ + + def __init__(self): + self._task_slug = None + self._model_version_slug = "" + self._id = 0 + self._state = BenchmarkTaskRunState.BENCHMARK_TASK_RUN_STATE_UNSPECIFIED + self._start_time = None + self._end_time = None + self._error_message = None + self._freeze() + + @property + def task_slug(self) -> Optional['ApiBenchmarkTaskSlug']: + """Task that was invoked.""" + return self._task_slug + + @task_slug.setter + def task_slug(self, task_slug: Optional['ApiBenchmarkTaskSlug']): + if task_slug is None: + del self.task_slug + return + if not isinstance(task_slug, ApiBenchmarkTaskSlug): + raise TypeError('task_slug must be of type ApiBenchmarkTaskSlug') + self._task_slug = task_slug + + @property + def model_version_slug(self) -> str: + """Model candidate against the task.""" + return self._model_version_slug + + @model_version_slug.setter + def model_version_slug(self, model_version_slug: str): + if model_version_slug is None: + del self.model_version_slug + return + if not isinstance(model_version_slug, str): + raise TypeError('model_version_slug must be of type str') + self._model_version_slug = model_version_slug + + @property + def id(self) -> int: + """Run identifier.""" + 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 state(self) -> 'BenchmarkTaskRunState': + """State of the run""" + return self._state + + @state.setter + def state(self, state: 'BenchmarkTaskRunState'): + if state is None: + del self.state + return + if not isinstance(state, BenchmarkTaskRunState): + raise TypeError('state must be of type BenchmarkTaskRunState') + self._state = state + + @property + def start_time(self) -> datetime: + """Start time of the run""" + return self._start_time or None + + @start_time.setter + def start_time(self, start_time: Optional[datetime]): + if start_time is None: + del self.start_time + return + if not isinstance(start_time, datetime): + raise TypeError('start_time must be of type datetime') + self._start_time = start_time + + @property + def end_time(self) -> datetime: + """End time of the run""" + return self._end_time or None + + @end_time.setter + def end_time(self, end_time: Optional[datetime]): + if end_time is None: + del self.end_time + return + if not isinstance(end_time, datetime): + raise TypeError('end_time must be of type datetime') + self._end_time = end_time + + @property + def error_message(self) -> str: + """Error message if the run failed""" + return self._error_message or "" + + @error_message.setter + def error_message(self, error_message: Optional[str]): + if error_message is None: + del self.error_message + return + if not isinstance(error_message, str): + raise TypeError('error_message must be of type str') + self._error_message = error_message + + +class ApiBenchmarkTaskSlug(KaggleObject): + r""" + This is an identifier, equivalent of a task version ID + + Attributes: + owner_slug (str) + The owner slug + If omitted: use the current user's slug + task_slug (str) + The task slug + version_number (int) + Version number + If omitted: use the latest version + """ + + def __init__(self): + self._owner_slug = None + self._task_slug = "" + self._version_number = None + self._freeze() + + @property + def owner_slug(self) -> str: + r""" + The owner slug + If omitted: use the current user's slug + """ + return self._owner_slug or "" + + @owner_slug.setter + def owner_slug(self, owner_slug: Optional[str]): + if owner_slug is None: + del self.owner_slug + return + if not isinstance(owner_slug, str): + raise TypeError('owner_slug must be of type str') + self._owner_slug = owner_slug + + @property + def task_slug(self) -> str: + """The task slug""" + return self._task_slug + + @task_slug.setter + def task_slug(self, task_slug: str): + if task_slug is None: + del self.task_slug + return + if not isinstance(task_slug, str): + raise TypeError('task_slug must be of type str') + self._task_slug = task_slug + + @property + def version_number(self) -> int: + r""" + Version number + If omitted: use the latest version + """ + 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 + + +class ApiCreateBenchmarkTaskRequest(KaggleObject): + r""" + Attributes: + slug (str) + The slug for the task without the user's namespace. (ex: my-task instead of + username/my-task). This should match the slug in the kaggle-benchmarks + decorator in the code. + text (str) + The task's (or task version's) source code + """ + + def __init__(self): + self._slug = "" + self._text = "" + self._freeze() + + @property + def slug(self) -> str: + r""" + The slug for the task without the user's namespace. (ex: my-task instead of + username/my-task). This should match the slug in the kaggle-benchmarks + decorator in the code. + """ + return self._slug + + @slug.setter + def slug(self, slug: str): + if slug is None: + del self.slug + return + if not isinstance(slug, str): + raise TypeError('slug must be of type str') + self._slug = slug + + @property + def text(self) -> str: + """The task's (or task version's) source code""" + return self._text + + @text.setter + def text(self, text: str): + if text is None: + del self.text + return + if not isinstance(text, str): + raise TypeError('text must be of type str') + self._text = text + + def endpoint(self): + path = '/api/v1/benchmarks/tasks/push' + return path.format_map(self.to_field_map(self)) + + + @staticmethod + def method(): + return 'POST' + + @staticmethod + def body_fields(): + return '*' + + +class ApiDownloadBenchmarkTaskRunOutputRequest(KaggleObject): + r""" + Attributes: + run_id (int) + """ + + def __init__(self): + self._run_id = 0 + self._freeze() + + @property + def run_id(self) -> int: + return self._run_id + + @run_id.setter + def run_id(self, run_id: int): + if run_id is None: + del self.run_id + return + if not isinstance(run_id, int): + raise TypeError('run_id must be of type int') + self._run_id = run_id + + def endpoint(self): + path = '/api/v1/benchmarks/tasks/runs/{run_id}/output' + return path.format_map(self.to_field_map(self)) + + @staticmethod + def endpoint_path(): + return '/api/v1/benchmarks/tasks/runs/{run_id}/output' + + +class ApiGetBenchmarkTaskQuotaRequest(KaggleObject): + r""" + """ + + pass + def endpoint(self): + path = '/api/v1/benchmarks/tasks/quota' + return path.format_map(self.to_field_map(self)) + + +class ApiGetBenchmarkTaskQuotaResponse(KaggleObject): + r""" + Attributes: + daily_quota_used (float) + How much quota that was used in the time period (daily), in USD. + total_daily_quota_allowed (float) + Upper limit of allowed quota in the time period (daily), in USD. + """ + + def __init__(self): + self._daily_quota_used = 0.0 + self._total_daily_quota_allowed = 0.0 + self._freeze() + + @property + def daily_quota_used(self) -> float: + """How much quota that was used in the time period (daily), in USD.""" + return self._daily_quota_used + + @daily_quota_used.setter + def daily_quota_used(self, daily_quota_used: float): + if daily_quota_used is None: + del self.daily_quota_used + return + if not isinstance(daily_quota_used, float): + raise TypeError('daily_quota_used must be of type float') + self._daily_quota_used = daily_quota_used + + @property + def total_daily_quota_allowed(self) -> float: + """Upper limit of allowed quota in the time period (daily), in USD.""" + return self._total_daily_quota_allowed + + @total_daily_quota_allowed.setter + def total_daily_quota_allowed(self, total_daily_quota_allowed: float): + if total_daily_quota_allowed is None: + del self.total_daily_quota_allowed + return + if not isinstance(total_daily_quota_allowed, float): + raise TypeError('total_daily_quota_allowed must be of type float') + self._total_daily_quota_allowed = total_daily_quota_allowed + + @property + def dailyQuotaUsed(self): + return self.daily_quota_used + + @property + def totalDailyQuotaAllowed(self): + return self.total_daily_quota_allowed + + +class ApiGetBenchmarkTaskRequest(KaggleObject): + r""" + Attributes: + slug (ApiBenchmarkTaskSlug) + """ + + def __init__(self): + self._slug = None + self._freeze() + + @property + def slug(self) -> Optional['ApiBenchmarkTaskSlug']: + 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 + + def endpoint(self): + path = '/api/v1/benchmarks/tasks/{slug.task_slug}' + return path.format_map(self.to_field_map(self)) + + @staticmethod + def endpoint_path(): + return '/api/v1/benchmarks/tasks/{slug.task_slug}' + + +class ApiListBenchmarkTaskRunsRequest(KaggleObject): + r""" + Attributes: + task_slugs (ApiBenchmarkTaskSlug) + model_version_slugs (str) + """ + + def __init__(self): + self._task_slugs = [] + self._model_version_slugs = [] + self._freeze() + + @property + def task_slugs(self) -> Optional[List[Optional['ApiBenchmarkTaskSlug']]]: + 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 + + @property + def model_version_slugs(self) -> Optional[List[str]]: + return self._model_version_slugs + + @model_version_slugs.setter + def model_version_slugs(self, model_version_slugs: Optional[List[str]]): + if model_version_slugs is None: + del self.model_version_slugs + return + if not isinstance(model_version_slugs, list): + raise TypeError('model_version_slugs must be of type list') + if not all([isinstance(t, str) for t in model_version_slugs]): + raise TypeError('model_version_slugs must contain only items of type str') + self._model_version_slugs = model_version_slugs + + def endpoint(self): + path = '/api/v1/benchmarks/tasks/runs/list' + return path.format_map(self.to_field_map(self)) + + +class ApiListBenchmarkTaskRunsResponse(KaggleObject): + r""" + Attributes: + runs (ApiBenchmarkTaskRun) + """ + + def __init__(self): + self._runs = [] + self._freeze() + + @property + def runs(self) -> Optional[List[Optional['ApiBenchmarkTaskRun']]]: + return self._runs + + @runs.setter + def runs(self, runs: Optional[List[Optional['ApiBenchmarkTaskRun']]]): + if runs is None: + del self.runs + return + if not isinstance(runs, list): + raise TypeError('runs must be of type list') + if not all([isinstance(t, ApiBenchmarkTaskRun) for t in runs]): + raise TypeError('runs must contain only items of type ApiBenchmarkTaskRun') + self._runs = runs + + +class ApiListBenchmarkTasksRequest(KaggleObject): + r""" + Attributes: + status_filter (str) + Filter by task creation status (e.g. 'created', 'error'). + regex_filter (str) + Filter task slugs by regular expression. + """ + + def __init__(self): + self._status_filter = None + self._regex_filter = None + self._freeze() + + @property + def status_filter(self) -> str: + """Filter by task creation status (e.g. 'created', 'error').""" + return self._status_filter or "" + + @status_filter.setter + def status_filter(self, status_filter: Optional[str]): + if status_filter is None: + del self.status_filter + return + if not isinstance(status_filter, str): + raise TypeError('status_filter must be of type str') + self._status_filter = status_filter + + @property + def regex_filter(self) -> str: + """Filter task slugs by regular expression.""" + return self._regex_filter or "" + + @regex_filter.setter + def regex_filter(self, regex_filter: Optional[str]): + if regex_filter is None: + del self.regex_filter + return + if not isinstance(regex_filter, str): + raise TypeError('regex_filter must be of type str') + self._regex_filter = regex_filter + + def endpoint(self): + path = '/api/v1/benchmarks/tasks/list' + return path.format_map(self.to_field_map(self)) + + +class ApiListBenchmarkTasksResponse(KaggleObject): + r""" + Attributes: + tasks (ApiBenchmarkTask) + """ + + def __init__(self): + self._tasks = [] + self._freeze() + + @property + def tasks(self) -> Optional[List[Optional['ApiBenchmarkTask']]]: + return self._tasks + + @tasks.setter + def tasks(self, tasks: Optional[List[Optional['ApiBenchmarkTask']]]): + if tasks is None: + del self.tasks + return + if not isinstance(tasks, list): + raise TypeError('tasks must be of type list') + if not all([isinstance(t, ApiBenchmarkTask) for t in tasks]): + raise TypeError('tasks must contain only items of type ApiBenchmarkTask') + self._tasks = tasks + + +ApiBatchScheduleBenchmarkTaskRunsRequest._fields = [ + FieldMetadata("taskSlugs", "task_slugs", "_task_slugs", ApiBenchmarkTaskSlug, [], ListSerializer(KaggleObjectSerializer())), + FieldMetadata("modelVersionSlugs", "model_version_slugs", "_model_version_slugs", str, [], ListSerializer(PredefinedSerializer())), +] + +ApiBatchScheduleBenchmarkTaskRunsResponse._fields = [ + FieldMetadata("results", "results", "_results", BatchScheduleBenchmarkModelVersionResult, [], ListSerializer(KaggleObjectSerializer())), +] + +ApiBenchmarkTask._fields = [ + FieldMetadata("slug", "slug", "_slug", ApiBenchmarkTaskSlug, None, KaggleObjectSerializer()), + FieldMetadata("url", "url", "_url", str, "", PredefinedSerializer()), + FieldMetadata("error", "error", "_error", str, None, PredefinedSerializer(), optional=True), + FieldMetadata("creationState", "creation_state", "_creation_state", BenchmarkTaskVersionCreationState, BenchmarkTaskVersionCreationState.BENCHMARK_TASK_VERSION_CREATION_STATE_UNSPECIFIED, EnumSerializer()), + FieldMetadata("createTime", "create_time", "_create_time", datetime, None, DateTimeSerializer()), +] + +ApiBenchmarkTaskRun._fields = [ + FieldMetadata("taskSlug", "task_slug", "_task_slug", ApiBenchmarkTaskSlug, None, KaggleObjectSerializer()), + FieldMetadata("modelVersionSlug", "model_version_slug", "_model_version_slug", str, "", PredefinedSerializer()), + FieldMetadata("id", "id", "_id", int, 0, PredefinedSerializer()), + FieldMetadata("state", "state", "_state", BenchmarkTaskRunState, BenchmarkTaskRunState.BENCHMARK_TASK_RUN_STATE_UNSPECIFIED, EnumSerializer()), + FieldMetadata("startTime", "start_time", "_start_time", datetime, None, DateTimeSerializer(), optional=True), + FieldMetadata("endTime", "end_time", "_end_time", datetime, None, DateTimeSerializer(), optional=True), + FieldMetadata("errorMessage", "error_message", "_error_message", str, None, PredefinedSerializer(), optional=True), +] + +ApiBenchmarkTaskSlug._fields = [ + FieldMetadata("ownerSlug", "owner_slug", "_owner_slug", str, None, PredefinedSerializer(), optional=True), + FieldMetadata("taskSlug", "task_slug", "_task_slug", str, "", PredefinedSerializer()), + FieldMetadata("versionNumber", "version_number", "_version_number", int, None, PredefinedSerializer(), optional=True), +] + +ApiCreateBenchmarkTaskRequest._fields = [ + FieldMetadata("slug", "slug", "_slug", str, "", PredefinedSerializer()), + FieldMetadata("text", "text", "_text", str, "", PredefinedSerializer()), +] + +ApiDownloadBenchmarkTaskRunOutputRequest._fields = [ + FieldMetadata("runId", "run_id", "_run_id", int, 0, PredefinedSerializer()), +] + +ApiGetBenchmarkTaskQuotaRequest._fields = [] + +ApiGetBenchmarkTaskQuotaResponse._fields = [ + FieldMetadata("dailyQuotaUsed", "daily_quota_used", "_daily_quota_used", float, 0.0, PredefinedSerializer()), + FieldMetadata("totalDailyQuotaAllowed", "total_daily_quota_allowed", "_total_daily_quota_allowed", float, 0.0, PredefinedSerializer()), +] + +ApiGetBenchmarkTaskRequest._fields = [ + FieldMetadata("slug", "slug", "_slug", ApiBenchmarkTaskSlug, None, KaggleObjectSerializer()), +] + +ApiListBenchmarkTaskRunsRequest._fields = [ + FieldMetadata("taskSlugs", "task_slugs", "_task_slugs", ApiBenchmarkTaskSlug, [], ListSerializer(KaggleObjectSerializer())), + FieldMetadata("modelVersionSlugs", "model_version_slugs", "_model_version_slugs", str, [], ListSerializer(PredefinedSerializer())), +] + +ApiListBenchmarkTaskRunsResponse._fields = [ + FieldMetadata("runs", "runs", "_runs", ApiBenchmarkTaskRun, [], ListSerializer(KaggleObjectSerializer())), +] + +ApiListBenchmarkTasksRequest._fields = [ + FieldMetadata("statusFilter", "status_filter", "_status_filter", str, None, PredefinedSerializer(), optional=True), + FieldMetadata("regexFilter", "regex_filter", "_regex_filter", str, None, PredefinedSerializer(), optional=True), +] + +ApiListBenchmarkTasksResponse._fields = [ + FieldMetadata("tasks", "tasks", "_tasks", ApiBenchmarkTask, [], ListSerializer(KaggleObjectSerializer())), +] + diff --git a/kagglesdk/benchmarks/types/benchmark_types.py b/kagglesdk/benchmarks/types/benchmark_types.py index 13fb3a8..6579861 100644 --- a/kagglesdk/benchmarks/types/benchmark_types.py +++ b/kagglesdk/benchmarks/types/benchmark_types.py @@ -1,7 +1,544 @@ from datetime import datetime +from kagglesdk.benchmarks.types.benchmark_enums import BenchmarkModelImportanceLevel from kagglesdk.kaggle_object import * +from kagglesdk.licenses.types.licenses_types import License +from kagglesdk.users.types.legacy_organizations_service import OrganizationCard from typing import Optional, List +class BenchmarkModel(KaggleObject): + r""" + Attributes: + id (int) + This benchmark model's id. + display_name (str) + The display name of the model (plus variation). ex: 'Gemini 1.5 Pro' + slug (str) + The slug of the model (plus variation). ex: 'gemini-1.5-pro' + organization_id (int) + The organization that published the model. + owner_user_id (int) + The user that owns / created this model. + Filled automatically while creating, can be updated later. + license_id (int) + The license for this model. + default_version_id (int) + The default version to use for this model. + Filled automatically while creating, can be updated later. + version (BenchmarkModelVersion) + The version associated with this benchmark model. + * CREATE : first version to be created with the parent benchmark model. + * GET : specified version or default if none was specified. + * UPDATE : unused (use UpdateBenchmarkModelVersion). + organization (OrganizationCard) + The associated Organization, if any. Ignored on create and update. + license (License) + The associated License. Ignored on create and update. + published (bool) + Whether the benchmark model is published (iff ContentStateId == PUBLISHED). + """ + + def __init__(self): + self._id = 0 + self._display_name = "" + self._slug = "" + self._organization_id = None + self._owner_user_id = None + self._license_id = 0 + self._default_version_id = None + self._version = None + self._organization = None + self._license = None + self._published = False + self._freeze() + + @property + def id(self) -> int: + """This benchmark model's 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 display_name(self) -> str: + """The display name of the model (plus variation). ex: 'Gemini 1.5 Pro'""" + return self._display_name + + @display_name.setter + def display_name(self, display_name: 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 slug(self) -> str: + """The slug of the model (plus variation). ex: 'gemini-1.5-pro'""" + return self._slug + + @slug.setter + def slug(self, slug: str): + if slug is None: + del self.slug + return + if not isinstance(slug, str): + raise TypeError('slug must be of type str') + self._slug = slug + + @property + def organization_id(self) -> int: + """The organization that published the model.""" + return self._organization_id or 0 + + @organization_id.setter + def organization_id(self, organization_id: Optional[int]): + if organization_id is None: + del self.organization_id + return + if not isinstance(organization_id, int): + raise TypeError('organization_id must be of type int') + self._organization_id = organization_id + + @property + def owner_user_id(self) -> int: + r""" + The user that owns / created this model. + Filled automatically while creating, can be updated later. + """ + return self._owner_user_id or 0 + + @owner_user_id.setter + def owner_user_id(self, owner_user_id: Optional[int]): + if owner_user_id is None: + del self.owner_user_id + return + if not isinstance(owner_user_id, int): + raise TypeError('owner_user_id must be of type int') + self._owner_user_id = owner_user_id + + @property + def license_id(self) -> int: + """The license for this model.""" + return self._license_id + + @license_id.setter + def license_id(self, license_id: int): + if license_id is None: + del self.license_id + return + if not isinstance(license_id, int): + raise TypeError('license_id must be of type int') + self._license_id = license_id + + @property + def default_version_id(self) -> int: + r""" + The default version to use for this model. + Filled automatically while creating, can be updated later. + """ + return self._default_version_id or 0 + + @default_version_id.setter + def default_version_id(self, default_version_id: Optional[int]): + if default_version_id is None: + del self.default_version_id + return + if not isinstance(default_version_id, int): + raise TypeError('default_version_id must be of type int') + self._default_version_id = default_version_id + + @property + def version(self) -> Optional['BenchmarkModelVersion']: + r""" + The version associated with this benchmark model. + * CREATE : first version to be created with the parent benchmark model. + * GET : specified version or default if none was specified. + * UPDATE : unused (use UpdateBenchmarkModelVersion). + """ + return self._version or None + + @version.setter + def version(self, version: Optional[Optional['BenchmarkModelVersion']]): + if version is None: + del self.version + return + if not isinstance(version, BenchmarkModelVersion): + raise TypeError('version must be of type BenchmarkModelVersion') + self._version = version + + @property + def organization(self) -> Optional['OrganizationCard']: + """The associated Organization, if any. Ignored on create and update.""" + return self._organization + + @organization.setter + def organization(self, organization: Optional['OrganizationCard']): + if organization is None: + del self.organization + return + if not isinstance(organization, OrganizationCard): + raise TypeError('organization must be of type OrganizationCard') + self._organization = organization + + @property + def license(self) -> Optional['License']: + """The associated License. Ignored on create and update.""" + return self._license + + @license.setter + def license(self, license: Optional['License']): + if license is None: + del self.license + return + if not isinstance(license, License): + raise TypeError('license must be of type License') + self._license = license + + @property + def published(self) -> bool: + """Whether the benchmark model is published (iff ContentStateId == PUBLISHED).""" + return self._published + + @published.setter + def published(self, published: bool): + if published is None: + del self.published + return + if not isinstance(published, bool): + raise TypeError('published must be of type bool') + self._published = published + + +class BenchmarkModelVersion(KaggleObject): + r""" + Attributes: + id (int) + The id of the benchmark model version. + benchmark_model_id (int) + The id of the parent benchmark model. + slug (str) + The slug of the model version. ex: 'gemini-1.5-pro-001' + Required for CREATE, can be updated later. + external_url (str) + An external link to a resource explaining the model version. ex: blog post, + aistudio, etc. + knowledge_cutoff (datetime) + A cutoff date for training data for the model. + is_default (bool) + Whether this BenchmarkModelVersion is the default for the parent + BenchmarkModel. + published (bool) + Whether the model version is published (iff ContentStateId == PUBLISHED and + parent benchmark model has ContentStateId == PUBLISHED). + allow_model_proxy (bool) + Whether this BenchmarkModelVersion is supported by model proxy. + model_proxy_slug (str) + The slug used by model proxy. ex: 'google/gemini-2.5-pro'. + Only set when `allow_model_proxy` is true. + display_name (str) + description (str) + organization (OrganizationCard) + Fields from the model for convenience + name (str) + license (License) + importance_level (BenchmarkModelImportanceLevel) + Whether this model version is run on Kaggle-maintained benchmarks + input_modalities (str) + Comma-separated input modalities supported by this model version. + Valid values: 'text', 'image', 'video', 'audio'. + Example: 'text,image' + output_modalities (str) + Comma-separated output modalities supported by this model version. + Valid values: 'text', 'image', 'video', 'audio'. + Example: 'text,image' + """ + + def __init__(self): + self._id = 0 + self._benchmark_model_id = 0 + self._slug = "" + self._external_url = None + self._knowledge_cutoff = None + self._is_default = False + self._published = False + self._allow_model_proxy = False + self._model_proxy_slug = None + self._display_name = None + self._description = None + self._organization = None + self._name = None + self._license = None + self._importance_level = None + self._input_modalities = None + self._output_modalities = None + self._freeze() + + @property + def id(self) -> int: + """The id of the benchmark model version.""" + 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 benchmark_model_id(self) -> int: + """The id of the parent benchmark model.""" + return self._benchmark_model_id + + @benchmark_model_id.setter + def benchmark_model_id(self, benchmark_model_id: int): + if benchmark_model_id is None: + del self.benchmark_model_id + return + if not isinstance(benchmark_model_id, int): + raise TypeError('benchmark_model_id must be of type int') + self._benchmark_model_id = benchmark_model_id + + @property + def slug(self) -> str: + r""" + The slug of the model version. ex: 'gemini-1.5-pro-001' + Required for CREATE, can be updated later. + """ + return self._slug + + @slug.setter + def slug(self, slug: str): + if slug is None: + del self.slug + return + if not isinstance(slug, str): + raise TypeError('slug must be of type str') + self._slug = slug + + @property + def external_url(self) -> str: + r""" + An external link to a resource explaining the model version. ex: blog post, + aistudio, etc. + """ + return self._external_url or "" + + @external_url.setter + def external_url(self, external_url: Optional[str]): + if external_url is None: + del self.external_url + return + if not isinstance(external_url, str): + raise TypeError('external_url must be of type str') + self._external_url = external_url + + @property + def knowledge_cutoff(self) -> datetime: + """A cutoff date for training data for the model.""" + return self._knowledge_cutoff or None + + @knowledge_cutoff.setter + def knowledge_cutoff(self, knowledge_cutoff: Optional[datetime]): + if knowledge_cutoff is None: + del self.knowledge_cutoff + return + if not isinstance(knowledge_cutoff, datetime): + raise TypeError('knowledge_cutoff must be of type datetime') + self._knowledge_cutoff = knowledge_cutoff + + @property + def is_default(self) -> bool: + r""" + Whether this BenchmarkModelVersion is the default for the parent + BenchmarkModel. + """ + return self._is_default + + @is_default.setter + def is_default(self, is_default: bool): + if is_default is None: + del self.is_default + return + if not isinstance(is_default, bool): + raise TypeError('is_default must be of type bool') + self._is_default = is_default + + @property + def published(self) -> bool: + r""" + Whether the model version is published (iff ContentStateId == PUBLISHED and + parent benchmark model has ContentStateId == PUBLISHED). + """ + return self._published + + @published.setter + def published(self, published: bool): + if published is None: + del self.published + return + if not isinstance(published, bool): + raise TypeError('published must be of type bool') + self._published = published + + @property + def allow_model_proxy(self) -> bool: + """Whether this BenchmarkModelVersion is supported by model proxy.""" + return self._allow_model_proxy + + @allow_model_proxy.setter + def allow_model_proxy(self, allow_model_proxy: bool): + if allow_model_proxy is None: + del self.allow_model_proxy + return + if not isinstance(allow_model_proxy, bool): + raise TypeError('allow_model_proxy must be of type bool') + self._allow_model_proxy = allow_model_proxy + + @property + def model_proxy_slug(self) -> str: + r""" + The slug used by model proxy. ex: 'google/gemini-2.5-pro'. + Only set when `allow_model_proxy` is true. + """ + return self._model_proxy_slug or "" + + @model_proxy_slug.setter + def model_proxy_slug(self, model_proxy_slug: Optional[str]): + if model_proxy_slug is None: + del self.model_proxy_slug + return + if not isinstance(model_proxy_slug, str): + raise TypeError('model_proxy_slug must be of type str') + self._model_proxy_slug = model_proxy_slug + + @property + def display_name(self) -> str: + 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 description(self) -> str: + 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 name(self) -> str: + return self._name or "" + + @name.setter + def name(self, name: Optional[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 organization(self) -> Optional['OrganizationCard']: + """Fields from the model for convenience""" + return self._organization or None + + @organization.setter + def organization(self, organization: Optional[Optional['OrganizationCard']]): + if organization is None: + del self.organization + return + if not isinstance(organization, OrganizationCard): + raise TypeError('organization must be of type OrganizationCard') + self._organization = organization + + @property + def license(self) -> Optional['License']: + return self._license + + @license.setter + def license(self, license: Optional['License']): + if license is None: + del self.license + return + if not isinstance(license, License): + raise TypeError('license must be of type License') + self._license = license + + @property + def importance_level(self) -> 'BenchmarkModelImportanceLevel': + """Whether this model version is run on Kaggle-maintained benchmarks""" + return self._importance_level or BenchmarkModelImportanceLevel.BENCHMARK_MODEL_IMPORTANCE_LEVEL_UNSPECIFIED + + @importance_level.setter + def importance_level(self, importance_level: Optional['BenchmarkModelImportanceLevel']): + if importance_level is None: + del self.importance_level + return + if not isinstance(importance_level, BenchmarkModelImportanceLevel): + raise TypeError('importance_level must be of type BenchmarkModelImportanceLevel') + self._importance_level = importance_level + + @property + def input_modalities(self) -> str: + r""" + Comma-separated input modalities supported by this model version. + Valid values: 'text', 'image', 'video', 'audio'. + Example: 'text,image' + """ + return self._input_modalities or "" + + @input_modalities.setter + def input_modalities(self, input_modalities: Optional[str]): + if input_modalities is None: + del self.input_modalities + return + if not isinstance(input_modalities, str): + raise TypeError('input_modalities must be of type str') + self._input_modalities = input_modalities + + @property + def output_modalities(self) -> str: + r""" + Comma-separated output modalities supported by this model version. + Valid values: 'text', 'image', 'video', 'audio'. + Example: 'text,image' + """ + return self._output_modalities or "" + + @output_modalities.setter + def output_modalities(self, output_modalities: Optional[str]): + if output_modalities is None: + del self.output_modalities + return + if not isinstance(output_modalities, str): + raise TypeError('output_modalities must be of type str') + self._output_modalities = output_modalities + + class BenchmarkResult(KaggleObject): r""" TODO(bml): Integrate this proto with personal benchmarks trials. @@ -279,6 +816,40 @@ def minus(self, minus: float): self._minus = minus +BenchmarkModel._fields = [ + FieldMetadata("id", "id", "_id", int, 0, PredefinedSerializer()), + FieldMetadata("displayName", "display_name", "_display_name", str, "", PredefinedSerializer()), + FieldMetadata("slug", "slug", "_slug", str, "", PredefinedSerializer()), + FieldMetadata("organizationId", "organization_id", "_organization_id", int, None, PredefinedSerializer(), optional=True), + FieldMetadata("ownerUserId", "owner_user_id", "_owner_user_id", int, None, PredefinedSerializer(), optional=True), + FieldMetadata("licenseId", "license_id", "_license_id", int, 0, PredefinedSerializer()), + FieldMetadata("defaultVersionId", "default_version_id", "_default_version_id", int, None, PredefinedSerializer(), optional=True), + FieldMetadata("version", "version", "_version", BenchmarkModelVersion, None, KaggleObjectSerializer(), optional=True), + FieldMetadata("organization", "organization", "_organization", OrganizationCard, None, KaggleObjectSerializer()), + FieldMetadata("license", "license", "_license", License, None, KaggleObjectSerializer()), + FieldMetadata("published", "published", "_published", bool, False, PredefinedSerializer()), +] + +BenchmarkModelVersion._fields = [ + FieldMetadata("id", "id", "_id", int, 0, PredefinedSerializer()), + FieldMetadata("benchmarkModelId", "benchmark_model_id", "_benchmark_model_id", int, 0, PredefinedSerializer()), + FieldMetadata("slug", "slug", "_slug", str, "", PredefinedSerializer()), + FieldMetadata("externalUrl", "external_url", "_external_url", str, None, PredefinedSerializer(), optional=True), + FieldMetadata("knowledgeCutoff", "knowledge_cutoff", "_knowledge_cutoff", datetime, None, DateTimeSerializer(), optional=True), + FieldMetadata("isDefault", "is_default", "_is_default", bool, False, PredefinedSerializer()), + FieldMetadata("published", "published", "_published", bool, False, PredefinedSerializer()), + FieldMetadata("allowModelProxy", "allow_model_proxy", "_allow_model_proxy", bool, False, PredefinedSerializer()), + FieldMetadata("modelProxySlug", "model_proxy_slug", "_model_proxy_slug", str, None, PredefinedSerializer(), optional=True), + FieldMetadata("displayName", "display_name", "_display_name", str, None, PredefinedSerializer(), optional=True), + FieldMetadata("description", "description", "_description", str, None, PredefinedSerializer(), optional=True), + FieldMetadata("organization", "organization", "_organization", OrganizationCard, None, KaggleObjectSerializer(), optional=True), + FieldMetadata("name", "name", "_name", str, None, PredefinedSerializer(), optional=True), + FieldMetadata("license", "license", "_license", License, None, KaggleObjectSerializer()), + FieldMetadata("importanceLevel", "importance_level", "_importance_level", BenchmarkModelImportanceLevel, None, EnumSerializer(), optional=True), + FieldMetadata("inputModalities", "input_modalities", "_input_modalities", str, None, PredefinedSerializer(), optional=True), + FieldMetadata("outputModalities", "output_modalities", "_output_modalities", str, None, PredefinedSerializer(), optional=True), +] + BenchmarkResult._fields = [ FieldMetadata("numericResult", "numeric_result", "_numeric_result", NumericResult, None, KaggleObjectSerializer(), optional=True), FieldMetadata("booleanResult", "boolean_result", "_boolean_result", bool, None, PredefinedSerializer(), optional=True), diff --git a/kagglesdk/benchmarks/types/benchmarks_api_service.py b/kagglesdk/benchmarks/types/benchmarks_api_service.py index a088776..0d0d58c 100644 --- a/kagglesdk/benchmarks/types/benchmarks_api_service.py +++ b/kagglesdk/benchmarks/types/benchmarks_api_service.py @@ -1,4 +1,5 @@ -from kagglesdk.benchmarks.types.benchmark_types import BenchmarkResult +from google.protobuf.field_mask_pb2 import FieldMask +from kagglesdk.benchmarks.types.benchmark_types import BenchmarkModel, BenchmarkResult from kagglesdk.kaggle_object import * from typing import List, Optional @@ -218,6 +219,119 @@ def endpoint_path(): return '/api/v1/benchmarks/{owner_slug}/{benchmark_slug}/leaderboard' +class ApiListBenchmarkModelsRequest(KaggleObject): + r""" + Attributes: + page_size (int) + page_token (str) + read_mask (FieldMask) + """ + + def __init__(self): + self._page_size = 0 + self._page_token = "" + self._read_mask = None + self._freeze() + + @property + def page_size(self) -> int: + return self._page_size + + @page_size.setter + def page_size(self, page_size: int): + if page_size is None: + del self.page_size + return + if not isinstance(page_size, int): + raise TypeError('page_size must be of type int') + self._page_size = page_size + + @property + def page_token(self) -> str: + return self._page_token + + @page_token.setter + def page_token(self, page_token: str): + if page_token is None: + del self.page_token + return + if not isinstance(page_token, str): + raise TypeError('page_token must be of type str') + self._page_token = page_token + + @property + def read_mask(self) -> FieldMask: + return self._read_mask + + @read_mask.setter + def read_mask(self, read_mask: FieldMask): + if read_mask is None: + del self.read_mask + return + if not isinstance(read_mask, FieldMask): + raise TypeError('read_mask must be of type FieldMask') + self._read_mask = read_mask + + def endpoint(self): + path = '/api/v1/benchmarks/models' + return path.format_map(self.to_field_map(self)) + + +class ApiListBenchmarkModelsResponse(KaggleObject): + r""" + Attributes: + benchmark_models (BenchmarkModel) + NOTE: This reuses the internal BenchmarkModel directly. If BenchmarkModel + ever gets fields that shouldn't be public, introduce a dedicated API type. + next_page_token (str) + """ + + def __init__(self): + self._benchmark_models = [] + self._next_page_token = None + self._freeze() + + @property + def benchmark_models(self) -> Optional[List[Optional['BenchmarkModel']]]: + r""" + NOTE: This reuses the internal BenchmarkModel directly. If BenchmarkModel + ever gets fields that shouldn't be public, introduce a dedicated API type. + """ + return self._benchmark_models + + @benchmark_models.setter + def benchmark_models(self, benchmark_models: Optional[List[Optional['BenchmarkModel']]]): + if benchmark_models is None: + del self.benchmark_models + return + if not isinstance(benchmark_models, list): + raise TypeError('benchmark_models must be of type list') + if not all([isinstance(t, BenchmarkModel) for t in benchmark_models]): + raise TypeError('benchmark_models must contain only items of type BenchmarkModel') + self._benchmark_models = benchmark_models + + @property + def next_page_token(self) -> str: + return self._next_page_token or "" + + @next_page_token.setter + def next_page_token(self, next_page_token: Optional[str]): + if next_page_token is None: + del self.next_page_token + return + if not isinstance(next_page_token, str): + raise TypeError('next_page_token must be of type str') + self._next_page_token = next_page_token + + @property + def benchmarkModels(self): + return self.benchmark_models + + @property + def nextPageToken(self): + return self.next_page_token + + ApiBenchmarkLeaderboard.LeaderboardRow._fields = [ FieldMetadata("modelVersionName", "model_version_name", "_model_version_name", str, "", PredefinedSerializer()), FieldMetadata("modelVersionSlug", "model_version_slug", "_model_version_slug", str, "", PredefinedSerializer()), @@ -241,3 +355,14 @@ def endpoint_path(): FieldMetadata("versionNumber", "version_number", "_version_number", int, None, PredefinedSerializer(), optional=True), ] +ApiListBenchmarkModelsRequest._fields = [ + FieldMetadata("pageSize", "page_size", "_page_size", int, 0, PredefinedSerializer()), + FieldMetadata("pageToken", "page_token", "_page_token", str, "", PredefinedSerializer()), + FieldMetadata("readMask", "read_mask", "_read_mask", FieldMask, None, FieldMaskSerializer()), +] + +ApiListBenchmarkModelsResponse._fields = [ + FieldMetadata("benchmarkModels", "benchmark_models", "_benchmark_models", BenchmarkModel, [], ListSerializer(KaggleObjectSerializer())), + FieldMetadata("nextPageToken", "next_page_token", "_next_page_token", str, None, PredefinedSerializer(), optional=True), +] + diff --git a/kagglesdk/common/types/cropped_image_upload.py b/kagglesdk/common/types/cropped_image_upload.py new file mode 100644 index 0000000..26adc24 --- /dev/null +++ b/kagglesdk/common/types/cropped_image_upload.py @@ -0,0 +1,163 @@ +from kagglesdk.kaggle_object import * +from typing import Optional, List + +class CroppedImageRectangle(KaggleObject): + r""" + Attributes: + title (str) + Title of the crop (e.g. 'thumbnail'). + top (int) + left (int) + width (int) + height (int) + """ + + def __init__(self): + self._title = None + self._top = 0 + self._left = 0 + self._width = 0 + self._height = 0 + self._freeze() + + @property + def title(self) -> str: + """Title of the crop (e.g. 'thumbnail').""" + return self._title or "" + + @title.setter + def title(self, title: Optional[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 top(self) -> int: + return self._top + + @top.setter + def top(self, top: int): + if top is None: + del self.top + return + if not isinstance(top, int): + raise TypeError('top must be of type int') + self._top = top + + @property + def left(self) -> int: + return self._left + + @left.setter + def left(self, left: int): + if left is None: + del self.left + return + if not isinstance(left, int): + raise TypeError('left must be of type int') + self._left = left + + @property + def width(self) -> int: + return self._width + + @width.setter + def width(self, width: int): + if width is None: + del self.width + return + if not isinstance(width, int): + raise TypeError('width must be of type int') + self._width = width + + @property + def height(self) -> int: + return self._height + + @height.setter + def height(self, height: int): + if height is None: + del self.height + return + if not isinstance(height, int): + raise TypeError('height must be of type int') + self._height = height + + +class CroppedImageUpload(KaggleObject): + r""" + This is the result of our React component. + + Attributes: + token (str) + Token that represents the image blob. + It's optional since you can crop an existing image by URL and thus just + update the rectangle(s). + DEPRECATED: Value types are deprecated in favor of `optional`, though this + case may have been deemed difficult to migrate. + crop_rectangles (CroppedImageRectangle) + Cropped rectangles (i.e. for selecting a smaller rectangle from the image + in the token). + """ + + def __init__(self): + self._token = None + self._crop_rectangles = [] + self._freeze() + + @property + def token(self) -> str: + r""" + Token that represents the image blob. + It's optional since you can crop an existing image by URL and thus just + update the rectangle(s). + DEPRECATED: Value types are deprecated in favor of `optional`, though this + case may have been deemed difficult to migrate. + """ + return self._token or None + + @token.setter + def token(self, token: Optional[str]): + if token is None: + del self.token + return + if not isinstance(token, str): + raise TypeError('token must be of type str') + self._token = token + + @property + def crop_rectangles(self) -> Optional[List[Optional['CroppedImageRectangle']]]: + r""" + Cropped rectangles (i.e. for selecting a smaller rectangle from the image + in the token). + """ + return self._crop_rectangles + + @crop_rectangles.setter + def crop_rectangles(self, crop_rectangles: Optional[List[Optional['CroppedImageRectangle']]]): + if crop_rectangles is None: + del self.crop_rectangles + return + if not isinstance(crop_rectangles, list): + raise TypeError('crop_rectangles must be of type list') + if not all([isinstance(t, CroppedImageRectangle) for t in crop_rectangles]): + raise TypeError('crop_rectangles must contain only items of type CroppedImageRectangle') + self._crop_rectangles = crop_rectangles + + +CroppedImageRectangle._fields = [ + FieldMetadata("title", "title", "_title", str, None, PredefinedSerializer(), optional=True), + FieldMetadata("top", "top", "_top", int, 0, PredefinedSerializer()), + FieldMetadata("left", "left", "_left", int, 0, PredefinedSerializer()), + FieldMetadata("width", "width", "_width", int, 0, PredefinedSerializer()), + FieldMetadata("height", "height", "_height", int, 0, PredefinedSerializer()), +] + +CroppedImageUpload._fields = [ + FieldMetadata("token", "token", "_token", str, None, PredefinedSerializer(), optional=True), + FieldMetadata("cropRectangles", "crop_rectangles", "_crop_rectangles", CroppedImageRectangle, [], ListSerializer(KaggleObjectSerializer())), +] + diff --git a/kagglesdk/competitions/services/competition_api_service.py b/kagglesdk/competitions/services/competition_api_service.py index 5e455ca..aa5c1a6 100644 --- a/kagglesdk/competitions/services/competition_api_service.py +++ b/kagglesdk/competitions/services/competition_api_service.py @@ -1,6 +1,8 @@ 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, ApiCreateCodeSubmissionRequest, ApiCreateCodeSubmissionResponse, ApiCreateSubmissionRequest, ApiCreateSubmissionResponse, ApiDownloadDataFileRequest, ApiDownloadDataFilesRequest, ApiDownloadLeaderboardRequest, ApiGetCompetitionDataFilesSummaryRequest, ApiGetCompetitionRequest, ApiGetLeaderboardRequest, ApiGetLeaderboardResponse, ApiGetSubmissionRequest, ApiListCompetitionsRequest, ApiListCompetitionsResponse, ApiListDataFilesRequest, ApiListDataFilesResponse, ApiListDataTreeFilesRequest, ApiListSubmissionsRequest, ApiListSubmissionsResponse, ApiStartSubmissionUploadRequest, ApiStartSubmissionUploadResponse, ApiSubmission +from kagglesdk.competitions.types.competition_api_service import ApiCompetition, ApiCreateCodeSubmissionRequest, ApiCreateCodeSubmissionResponse, ApiCreateSubmissionRequest, ApiCreateSubmissionResponse, ApiDownloadDataFileRequest, ApiDownloadDataFilesRequest, ApiDownloadLeaderboardRequest, ApiGetCompetitionDataFilesSummaryRequest, ApiGetCompetitionRequest, ApiGetHackathonWriteUpRequest, ApiGetLeaderboardRequest, ApiGetLeaderboardResponse, ApiGetSubmissionRequest, ApiListCompetitionsRequest, ApiListCompetitionsResponse, ApiListDataFilesRequest, ApiListDataFilesResponse, ApiListDataTreeFilesRequest, ApiListHackathonWriteUpsRequest, ApiListSubmissionsRequest, ApiListSubmissionsResponse, ApiStartSubmissionUploadRequest, ApiStartSubmissionUploadResponse, ApiSubmission +from kagglesdk.competitions.types.hackathon_service import ListHackathonWriteUpsResponse +from kagglesdk.competitions.types.hackathons import HackathonWriteUp from kagglesdk.datasets.databundles.types.databundle_api_types import ApiDirectoryContent, ApiFilesSummary from kagglesdk.kaggle_http_client import KaggleHttpClient @@ -176,3 +178,27 @@ def get_competition_data_files_summary(self, request: ApiGetCompetitionDataFiles request = ApiGetCompetitionDataFilesSummaryRequest() return self._client.call("competitions.CompetitionApiService", "GetCompetitionDataFilesSummary", request, ApiFilesSummary) + + def list_hackathon_write_ups(self, request: ApiListHackathonWriteUpsRequest = None) -> ListHackathonWriteUpsResponse: + r""" + Args: + request (ApiListHackathonWriteUpsRequest): + The request object; initialized to empty instance if not specified. + """ + + if request is None: + request = ApiListHackathonWriteUpsRequest() + + return self._client.call("competitions.CompetitionApiService", "ListHackathonWriteUps", request, ListHackathonWriteUpsResponse) + + def get_hackathon_write_up(self, request: ApiGetHackathonWriteUpRequest = None) -> HackathonWriteUp: + r""" + Args: + request (ApiGetHackathonWriteUpRequest): + The request object; initialized to empty instance if not specified. + """ + + if request is None: + request = ApiGetHackathonWriteUpRequest() + + return self._client.call("competitions.CompetitionApiService", "GetHackathonWriteUp", request, HackathonWriteUp) diff --git a/kagglesdk/competitions/types/competition_api_service.py b/kagglesdk/competitions/types/competition_api_service.py index 5d237ea..bac0354 100644 --- a/kagglesdk/competitions/types/competition_api_service.py +++ b/kagglesdk/competitions/types/competition_api_service.py @@ -1136,6 +1136,53 @@ def endpoint_path(): return '/api/v1/competitions/get/{competition_name}' +class ApiGetHackathonWriteUpRequest(KaggleObject): + r""" + Attributes: + competition_name (str) + hackathon_write_up_id (int) + """ + + def __init__(self): + self._competition_name = "" + self._hackathon_write_up_id = 0 + 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 hackathon_write_up_id(self) -> int: + return self._hackathon_write_up_id + + @hackathon_write_up_id.setter + def hackathon_write_up_id(self, hackathon_write_up_id: int): + if hackathon_write_up_id is None: + del self.hackathon_write_up_id + return + if not isinstance(hackathon_write_up_id, int): + raise TypeError('hackathon_write_up_id must be of type int') + self._hackathon_write_up_id = hackathon_write_up_id + + def endpoint(self): + path = '/api/v1/competitions/{competition_name}/hackathon-write-ups/{hackathon_write_up_id}' + return path.format_map(self.to_field_map(self)) + + @staticmethod + def endpoint_path(): + return '/api/v1/competitions/{competition_name}/hackathon-write-ups/{hackathon_write_up_id}' + + class ApiGetLeaderboardRequest(KaggleObject): r""" Attributes: @@ -1774,6 +1821,100 @@ def endpoint_path(): return '/api/v1/competitions/{competition_name}/data-tree/list/' +class ApiListHackathonWriteUpsRequest(KaggleObject): + r""" + Attributes: + competition_name (str) + hackathon_track_ids (int) + winner (bool) + page_size (int) + page_token (str) + """ + + def __init__(self): + self._competition_name = "" + self._hackathon_track_ids = [] + self._winner = None + self._page_size = None + self._page_token = None + 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 hackathon_track_ids(self) -> Optional[List[int]]: + return self._hackathon_track_ids + + @hackathon_track_ids.setter + def hackathon_track_ids(self, hackathon_track_ids: Optional[List[int]]): + if hackathon_track_ids is None: + del self.hackathon_track_ids + return + if not isinstance(hackathon_track_ids, list): + raise TypeError('hackathon_track_ids must be of type list') + if not all([isinstance(t, int) for t in hackathon_track_ids]): + raise TypeError('hackathon_track_ids must contain only items of type int') + self._hackathon_track_ids = hackathon_track_ids + + @property + def winner(self) -> bool: + return self._winner or False + + @winner.setter + def winner(self, winner: Optional[bool]): + if winner is None: + del self.winner + return + if not isinstance(winner, bool): + raise TypeError('winner must be of type bool') + self._winner = winner + + @property + def page_size(self) -> int: + return self._page_size or 0 + + @page_size.setter + def page_size(self, page_size: Optional[int]): + if page_size is None: + del self.page_size + return + if not isinstance(page_size, int): + raise TypeError('page_size must be of type int') + self._page_size = page_size + + @property + def page_token(self) -> str: + return self._page_token or "" + + @page_token.setter + def page_token(self, page_token: Optional[str]): + if page_token is None: + del self.page_token + return + if not isinstance(page_token, str): + raise TypeError('page_token must be of type str') + self._page_token = page_token + + def endpoint(self): + path = '/api/v1/competitions/{competition_name}/hackathon-write-ups' + return path.format_map(self.to_field_map(self)) + + @staticmethod + def endpoint_path(): + return '/api/v1/competitions/{competition_name}/hackathon-write-ups' + + class ApiListSubmissionsRequest(KaggleObject): r""" Attributes: @@ -2360,6 +2501,11 @@ def url(self, url: Optional[str]): FieldMetadata("competitionName", "competition_name", "_competition_name", str, "", PredefinedSerializer()), ] +ApiGetHackathonWriteUpRequest._fields = [ + FieldMetadata("competitionName", "competition_name", "_competition_name", str, "", PredefinedSerializer()), + FieldMetadata("hackathonWriteUpId", "hackathon_write_up_id", "_hackathon_write_up_id", int, 0, PredefinedSerializer()), +] + ApiGetLeaderboardRequest._fields = [ FieldMetadata("competitionName", "competition_name", "_competition_name", str, "", PredefinedSerializer()), FieldMetadata("overridePublic", "override_public", "_override_public", bool, None, PredefinedSerializer(), optional=True), @@ -2417,6 +2563,14 @@ def url(self, url: Optional[str]): FieldMetadata("pageToken", "page_token", "_page_token", str, None, PredefinedSerializer(), optional=True), ] +ApiListHackathonWriteUpsRequest._fields = [ + FieldMetadata("competitionName", "competition_name", "_competition_name", str, "", PredefinedSerializer()), + FieldMetadata("hackathonTrackIds", "hackathon_track_ids", "_hackathon_track_ids", int, [], ListSerializer(PredefinedSerializer())), + FieldMetadata("winner", "winner", "_winner", bool, None, PredefinedSerializer(), optional=True), + FieldMetadata("pageSize", "page_size", "_page_size", int, None, PredefinedSerializer(), optional=True), + FieldMetadata("pageToken", "page_token", "_page_token", str, None, PredefinedSerializer(), optional=True), +] + ApiListSubmissionsRequest._fields = [ FieldMetadata("competitionName", "competition_name", "_competition_name", str, "", PredefinedSerializer()), FieldMetadata("sortBy", "sort_by", "_sort_by", SubmissionSortBy, SubmissionSortBy.SUBMISSION_SORT_BY_DATE, EnumSerializer()), diff --git a/kagglesdk/competitions/types/hackathon_service.py b/kagglesdk/competitions/types/hackathon_service.py new file mode 100644 index 0000000..960ed85 --- /dev/null +++ b/kagglesdk/competitions/types/hackathon_service.py @@ -0,0 +1,78 @@ +from kagglesdk.competitions.types.hackathons import HackathonWriteUp +from kagglesdk.kaggle_object import * +from typing import List, Optional + +class ListHackathonWriteUpsResponse(KaggleObject): + r""" + Attributes: + hackathon_write_ups (HackathonWriteUp) + next_page_token (str) + total_count (int) + """ + + def __init__(self): + self._hackathon_write_ups = [] + self._next_page_token = "" + self._total_count = 0 + self._freeze() + + @property + def hackathon_write_ups(self) -> Optional[List[Optional['HackathonWriteUp']]]: + return self._hackathon_write_ups + + @hackathon_write_ups.setter + def hackathon_write_ups(self, hackathon_write_ups: Optional[List[Optional['HackathonWriteUp']]]): + if hackathon_write_ups is None: + del self.hackathon_write_ups + return + if not isinstance(hackathon_write_ups, list): + raise TypeError('hackathon_write_ups must be of type list') + if not all([isinstance(t, HackathonWriteUp) for t in hackathon_write_ups]): + raise TypeError('hackathon_write_ups must contain only items of type HackathonWriteUp') + self._hackathon_write_ups = hackathon_write_ups + + @property + def next_page_token(self) -> str: + return self._next_page_token + + @next_page_token.setter + def next_page_token(self, next_page_token: str): + if next_page_token is None: + del self.next_page_token + return + if not isinstance(next_page_token, str): + raise TypeError('next_page_token must be of type str') + self._next_page_token = next_page_token + + @property + def total_count(self) -> int: + return self._total_count + + @total_count.setter + def total_count(self, total_count: int): + if total_count is None: + del self.total_count + return + if not isinstance(total_count, int): + raise TypeError('total_count must be of type int') + self._total_count = total_count + + @property + def hackathonWriteUps(self): + return self.hackathon_write_ups + + @property + def nextPageToken(self): + return self.next_page_token + + @property + def totalCount(self): + return self.total_count + + +ListHackathonWriteUpsResponse._fields = [ + FieldMetadata("hackathonWriteUps", "hackathon_write_ups", "_hackathon_write_ups", HackathonWriteUp, [], ListSerializer(KaggleObjectSerializer())), + FieldMetadata("nextPageToken", "next_page_token", "_next_page_token", str, "", PredefinedSerializer()), + FieldMetadata("totalCount", "total_count", "_total_count", int, 0, PredefinedSerializer()), +] + diff --git a/kagglesdk/competitions/types/hackathons.py b/kagglesdk/competitions/types/hackathons.py new file mode 100644 index 0000000..5a3784e --- /dev/null +++ b/kagglesdk/competitions/types/hackathons.py @@ -0,0 +1,165 @@ +from kagglesdk.competitions.types.team import Team +from kagglesdk.discussions.types.writeup_types import WriteUp +from kagglesdk.kaggle_object import * +from typing import Optional, List + +class HackathonWriteUp(KaggleObject): + r""" + Attributes: + id (int) + team (Team) + write_up (WriteUp) + template (bool) + hackathon_track_ids (int) + awarded_hackathon_track_prize_ids (int) + competition_id (int) + owner_host_user_id (int) + owner_judge_user_id (int) + """ + + def __init__(self): + self._id = 0 + self._team = None + self._write_up = None + self._template = False + self._hackathon_track_ids = [] + self._awarded_hackathon_track_prize_ids = [] + self._competition_id = 0 + self._owner_host_user_id = None + self._owner_judge_user_id = None + self._freeze() + + @property + def id(self) -> int: + 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 team(self) -> Optional['Team']: + return self._team or None + + @team.setter + def team(self, team: Optional[Optional['Team']]): + if team is None: + del self.team + return + if not isinstance(team, Team): + raise TypeError('team must be of type Team') + self._team = team + + @property + def write_up(self) -> Optional['WriteUp']: + return self._write_up + + @write_up.setter + def write_up(self, write_up: Optional['WriteUp']): + if write_up is None: + del self.write_up + return + if not isinstance(write_up, WriteUp): + raise TypeError('write_up must be of type WriteUp') + self._write_up = write_up + + @property + def template(self) -> bool: + return self._template + + @template.setter + def template(self, template: bool): + if template is None: + del self.template + return + if not isinstance(template, bool): + raise TypeError('template must be of type bool') + self._template = template + + @property + def hackathon_track_ids(self) -> Optional[List[int]]: + return self._hackathon_track_ids + + @hackathon_track_ids.setter + def hackathon_track_ids(self, hackathon_track_ids: Optional[List[int]]): + if hackathon_track_ids is None: + del self.hackathon_track_ids + return + if not isinstance(hackathon_track_ids, list): + raise TypeError('hackathon_track_ids must be of type list') + if not all([isinstance(t, int) for t in hackathon_track_ids]): + raise TypeError('hackathon_track_ids must contain only items of type int') + self._hackathon_track_ids = hackathon_track_ids + + @property + def awarded_hackathon_track_prize_ids(self) -> Optional[List[int]]: + return self._awarded_hackathon_track_prize_ids + + @awarded_hackathon_track_prize_ids.setter + def awarded_hackathon_track_prize_ids(self, awarded_hackathon_track_prize_ids: Optional[List[int]]): + if awarded_hackathon_track_prize_ids is None: + del self.awarded_hackathon_track_prize_ids + return + if not isinstance(awarded_hackathon_track_prize_ids, list): + raise TypeError('awarded_hackathon_track_prize_ids must be of type list') + if not all([isinstance(t, int) for t in awarded_hackathon_track_prize_ids]): + raise TypeError('awarded_hackathon_track_prize_ids must contain only items of type int') + self._awarded_hackathon_track_prize_ids = awarded_hackathon_track_prize_ids + + @property + def competition_id(self) -> int: + return self._competition_id + + @competition_id.setter + def competition_id(self, competition_id: int): + if competition_id is None: + del self.competition_id + return + if not isinstance(competition_id, int): + raise TypeError('competition_id must be of type int') + self._competition_id = competition_id + + @property + def owner_host_user_id(self) -> int: + return self._owner_host_user_id or 0 + + @owner_host_user_id.setter + def owner_host_user_id(self, owner_host_user_id: Optional[int]): + if owner_host_user_id is None: + del self.owner_host_user_id + return + if not isinstance(owner_host_user_id, int): + raise TypeError('owner_host_user_id must be of type int') + self._owner_host_user_id = owner_host_user_id + + @property + def owner_judge_user_id(self) -> int: + return self._owner_judge_user_id or 0 + + @owner_judge_user_id.setter + def owner_judge_user_id(self, owner_judge_user_id: Optional[int]): + if owner_judge_user_id is None: + del self.owner_judge_user_id + return + if not isinstance(owner_judge_user_id, int): + raise TypeError('owner_judge_user_id must be of type int') + self._owner_judge_user_id = owner_judge_user_id + + +HackathonWriteUp._fields = [ + FieldMetadata("id", "id", "_id", int, 0, PredefinedSerializer()), + FieldMetadata("team", "team", "_team", Team, None, KaggleObjectSerializer(), optional=True), + FieldMetadata("writeUp", "write_up", "_write_up", WriteUp, None, KaggleObjectSerializer()), + FieldMetadata("template", "template", "_template", bool, False, PredefinedSerializer()), + FieldMetadata("hackathonTrackIds", "hackathon_track_ids", "_hackathon_track_ids", int, [], ListSerializer(PredefinedSerializer())), + FieldMetadata("awardedHackathonTrackPrizeIds", "awarded_hackathon_track_prize_ids", "_awarded_hackathon_track_prize_ids", int, [], ListSerializer(PredefinedSerializer())), + 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), +] + diff --git a/kagglesdk/competitions/types/team.py b/kagglesdk/competitions/types/team.py new file mode 100644 index 0000000..f246bc3 --- /dev/null +++ b/kagglesdk/competitions/types/team.py @@ -0,0 +1,445 @@ +from datetime import datetime +from kagglesdk.kaggle_object import * +from kagglesdk.users.types.user_avatar import UserAvatar +from typing import Optional, List + +class Team(KaggleObject): + r""" + Attributes: + id (int) + team_name (str) + competition_id (int) + The ID of the competition that the team is entered in. + team_leader_id (int) + The userId of the team leader. Can be referenced with team_members to + determine the user name. + medal (int) + The current medal placement of this team. If comp is finalized, uses + the stored value representing final private leaderboard rank; otherwise + uses current public leaderboard rank. Value corresponds with + Users.Medal. + submission_count (int) + The number of leaderboard-valid submissions that this team has made + (submissions made before deadline with status Complete). This may differ + from counts related to submission limits, eg Pending submissions count + towards limits but not the leaderboard. + last_submission_date (datetime) + The date of this team's latest submission. + TODO(aip.dev/142): (-- api-linter: core::0142::time-field-names=disabled + --) + public_leaderboard_submission_id (int) + This will be kept up-to-date while comp is ongoing, if the Team has + valid submissions. + public_leaderboard_score_formatted (str) + This will be kept up-to-date while comp is ongoing. + This is intended to be a dupe of PublicLeaderboardSubmission.PublicScore + which is not ideal, but improves performance of GetLeaderboard. + public_leaderboard_rank (int) + This will be written when the comp is finalized and LB is 'locked'. + private_leaderboard_submission_id (int) + This will be written when the comp is finalized and LB is 'locked'. + private_leaderboard_score_formatted (str) + This will be written when the comp is finalized and LB is 'locked'. + This is intended to be a dupe of PrivateLeaderboardSubmission.PrivateScore + which is not ideal, but improves performance of GetLeaderboard. + private_leaderboard_rank (int) + This will be written when the comp is finalized and LB is 'locked'. + team_up_enabled (bool) + Whether this team has indicated that they are open to teaming up. + team_up_intro (str) + If this team opted into team up, their optional intro message for + prospective teammates on the leaderboard. + write_up_forum_topic_id (int) + ForumTopic of the team's solution writeup, if set. + benchmark_model_version_id (int) + Linked benchmark model version, if set. + team_members (UserAvatar) + The list of users on the team. + """ + + def __init__(self): + self._id = 0 + self._team_name = "" + self._competition_id = 0 + self._team_leader_id = None + self._medal = None + self._submission_count = None + self._last_submission_date = None + self._public_leaderboard_submission_id = None + self._public_leaderboard_score_formatted = None + self._public_leaderboard_rank = None + self._private_leaderboard_submission_id = None + self._private_leaderboard_score_formatted = None + self._private_leaderboard_rank = None + self._team_up_enabled = False + self._team_up_intro = None + self._write_up_forum_topic_id = None + self._benchmark_model_version_id = None + self._team_members = [] + self._freeze() + + @property + def id(self) -> int: + 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 team_name(self) -> str: + return self._team_name + + @team_name.setter + def team_name(self, team_name: str): + if team_name is None: + del self.team_name + return + if not isinstance(team_name, str): + raise TypeError('team_name must be of type str') + self._team_name = team_name + + @property + def competition_id(self) -> int: + """The ID of the competition that the team is entered in.""" + return self._competition_id + + @competition_id.setter + def competition_id(self, competition_id: int): + if competition_id is None: + del self.competition_id + return + if not isinstance(competition_id, int): + raise TypeError('competition_id must be of type int') + self._competition_id = competition_id + + @property + def team_leader_id(self) -> int: + r""" + The userId of the team leader. Can be referenced with team_members to + determine the user name. + """ + return self._team_leader_id or 0 + + @team_leader_id.setter + def team_leader_id(self, team_leader_id: Optional[int]): + if team_leader_id is None: + del self.team_leader_id + return + if not isinstance(team_leader_id, int): + raise TypeError('team_leader_id must be of type int') + self._team_leader_id = team_leader_id + + @property + def medal(self) -> int: + r""" + The current medal placement of this team. If comp is finalized, uses + the stored value representing final private leaderboard rank; otherwise + uses current public leaderboard rank. Value corresponds with + Users.Medal. + """ + return self._medal or 0 + + @medal.setter + def medal(self, medal: Optional[int]): + if medal is None: + del self.medal + return + if not isinstance(medal, int): + raise TypeError('medal must be of type int') + self._medal = medal + + @property + def submission_count(self) -> int: + r""" + The number of leaderboard-valid submissions that this team has made + (submissions made before deadline with status Complete). This may differ + from counts related to submission limits, eg Pending submissions count + towards limits but not the leaderboard. + """ + return self._submission_count or 0 + + @submission_count.setter + def submission_count(self, submission_count: Optional[int]): + if submission_count is None: + del self.submission_count + return + if not isinstance(submission_count, int): + raise TypeError('submission_count must be of type int') + self._submission_count = submission_count + + @property + def last_submission_date(self) -> datetime: + r""" + The date of this team's latest submission. + TODO(aip.dev/142): (-- api-linter: core::0142::time-field-names=disabled + --) + """ + return self._last_submission_date + + @last_submission_date.setter + def last_submission_date(self, last_submission_date: datetime): + if last_submission_date is None: + del self.last_submission_date + return + if not isinstance(last_submission_date, datetime): + raise TypeError('last_submission_date must be of type datetime') + self._last_submission_date = last_submission_date + + @property + def public_leaderboard_submission_id(self) -> int: + r""" + This will be kept up-to-date while comp is ongoing, if the Team has + valid submissions. + """ + return self._public_leaderboard_submission_id or 0 + + @public_leaderboard_submission_id.setter + def public_leaderboard_submission_id(self, public_leaderboard_submission_id: Optional[int]): + if public_leaderboard_submission_id is None: + del self.public_leaderboard_submission_id + return + if not isinstance(public_leaderboard_submission_id, int): + raise TypeError('public_leaderboard_submission_id must be of type int') + self._public_leaderboard_submission_id = public_leaderboard_submission_id + + @property + def public_leaderboard_score_formatted(self) -> str: + r""" + This will be kept up-to-date while comp is ongoing. + This is intended to be a dupe of PublicLeaderboardSubmission.PublicScore + which is not ideal, but improves performance of GetLeaderboard. + """ + return self._public_leaderboard_score_formatted or "" + + @public_leaderboard_score_formatted.setter + def public_leaderboard_score_formatted(self, public_leaderboard_score_formatted: Optional[str]): + if public_leaderboard_score_formatted is None: + del self.public_leaderboard_score_formatted + return + if not isinstance(public_leaderboard_score_formatted, str): + raise TypeError('public_leaderboard_score_formatted must be of type str') + self._public_leaderboard_score_formatted = public_leaderboard_score_formatted + + @property + def public_leaderboard_rank(self) -> int: + """This will be written when the comp is finalized and LB is 'locked'.""" + return self._public_leaderboard_rank or 0 + + @public_leaderboard_rank.setter + def public_leaderboard_rank(self, public_leaderboard_rank: Optional[int]): + if public_leaderboard_rank is None: + del self.public_leaderboard_rank + return + if not isinstance(public_leaderboard_rank, int): + raise TypeError('public_leaderboard_rank must be of type int') + self._public_leaderboard_rank = public_leaderboard_rank + + @property + def private_leaderboard_submission_id(self) -> int: + """This will be written when the comp is finalized and LB is 'locked'.""" + return self._private_leaderboard_submission_id or 0 + + @private_leaderboard_submission_id.setter + def private_leaderboard_submission_id(self, private_leaderboard_submission_id: Optional[int]): + if private_leaderboard_submission_id is None: + del self.private_leaderboard_submission_id + return + if not isinstance(private_leaderboard_submission_id, int): + raise TypeError('private_leaderboard_submission_id must be of type int') + self._private_leaderboard_submission_id = private_leaderboard_submission_id + + @property + def private_leaderboard_score_formatted(self) -> str: + r""" + This will be written when the comp is finalized and LB is 'locked'. + This is intended to be a dupe of PrivateLeaderboardSubmission.PrivateScore + which is not ideal, but improves performance of GetLeaderboard. + """ + return self._private_leaderboard_score_formatted or "" + + @private_leaderboard_score_formatted.setter + def private_leaderboard_score_formatted(self, private_leaderboard_score_formatted: Optional[str]): + if private_leaderboard_score_formatted is None: + del self.private_leaderboard_score_formatted + return + if not isinstance(private_leaderboard_score_formatted, str): + raise TypeError('private_leaderboard_score_formatted must be of type str') + self._private_leaderboard_score_formatted = private_leaderboard_score_formatted + + @property + def private_leaderboard_rank(self) -> int: + """This will be written when the comp is finalized and LB is 'locked'.""" + return self._private_leaderboard_rank or 0 + + @private_leaderboard_rank.setter + def private_leaderboard_rank(self, private_leaderboard_rank: Optional[int]): + if private_leaderboard_rank is None: + del self.private_leaderboard_rank + return + if not isinstance(private_leaderboard_rank, int): + raise TypeError('private_leaderboard_rank must be of type int') + self._private_leaderboard_rank = private_leaderboard_rank + + @property + def team_up_enabled(self) -> bool: + """Whether this team has indicated that they are open to teaming up.""" + return self._team_up_enabled + + @team_up_enabled.setter + def team_up_enabled(self, team_up_enabled: bool): + if team_up_enabled is None: + del self.team_up_enabled + return + if not isinstance(team_up_enabled, bool): + raise TypeError('team_up_enabled must be of type bool') + self._team_up_enabled = team_up_enabled + + @property + def team_up_intro(self) -> str: + r""" + If this team opted into team up, their optional intro message for + prospective teammates on the leaderboard. + """ + return self._team_up_intro or "" + + @team_up_intro.setter + def team_up_intro(self, team_up_intro: Optional[str]): + if team_up_intro is None: + del self.team_up_intro + return + if not isinstance(team_up_intro, str): + raise TypeError('team_up_intro must be of type str') + self._team_up_intro = team_up_intro + + @property + def write_up_forum_topic_id(self) -> int: + """ForumTopic of the team's solution writeup, if set.""" + return self._write_up_forum_topic_id or 0 + + @write_up_forum_topic_id.setter + def write_up_forum_topic_id(self, write_up_forum_topic_id: Optional[int]): + if write_up_forum_topic_id is None: + del self.write_up_forum_topic_id + return + if not isinstance(write_up_forum_topic_id, int): + raise TypeError('write_up_forum_topic_id must be of type int') + self._write_up_forum_topic_id = write_up_forum_topic_id + + @property + def benchmark_model_version_id(self) -> int: + """Linked benchmark model version, if set.""" + return self._benchmark_model_version_id or 0 + + @benchmark_model_version_id.setter + def benchmark_model_version_id(self, benchmark_model_version_id: Optional[int]): + if benchmark_model_version_id is None: + del self.benchmark_model_version_id + return + if not isinstance(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 team_members(self) -> Optional[List[Optional['UserAvatar']]]: + """The list of users on the team.""" + return self._team_members + + @team_members.setter + def team_members(self, team_members: Optional[List[Optional['UserAvatar']]]): + if team_members is None: + del self.team_members + return + if not isinstance(team_members, list): + raise TypeError('team_members must be of type list') + if not all([isinstance(t, UserAvatar) for t in team_members]): + raise TypeError('team_members must contain only items of type UserAvatar') + self._team_members = team_members + + +class TeamUpInfo(KaggleObject): + r""" + Attributes: + enabled (bool) + team_leader (UserAvatar) + intro (str) + """ + + def __init__(self): + self._enabled = False + self._team_leader = None + self._intro = None + self._freeze() + + @property + def enabled(self) -> bool: + return self._enabled + + @enabled.setter + def enabled(self, enabled: bool): + if enabled is None: + del self.enabled + return + if not isinstance(enabled, bool): + raise TypeError('enabled must be of type bool') + self._enabled = enabled + + @property + def team_leader(self) -> Optional['UserAvatar']: + return self._team_leader + + @team_leader.setter + def team_leader(self, team_leader: Optional['UserAvatar']): + if team_leader is None: + del self.team_leader + return + if not isinstance(team_leader, UserAvatar): + raise TypeError('team_leader must be of type UserAvatar') + self._team_leader = team_leader + + @property + def intro(self) -> str: + return self._intro or "" + + @intro.setter + def intro(self, intro: Optional[str]): + if intro is None: + del self.intro + return + if not isinstance(intro, str): + raise TypeError('intro must be of type str') + self._intro = intro + + +Team._fields = [ + FieldMetadata("id", "id", "_id", int, 0, PredefinedSerializer()), + FieldMetadata("teamName", "team_name", "_team_name", str, "", PredefinedSerializer()), + FieldMetadata("competitionId", "competition_id", "_competition_id", int, 0, PredefinedSerializer()), + FieldMetadata("teamLeaderId", "team_leader_id", "_team_leader_id", int, None, PredefinedSerializer(), optional=True), + FieldMetadata("medal", "medal", "_medal", int, None, PredefinedSerializer(), optional=True), + FieldMetadata("submissionCount", "submission_count", "_submission_count", int, None, PredefinedSerializer(), optional=True), + FieldMetadata("lastSubmissionDate", "last_submission_date", "_last_submission_date", datetime, None, DateTimeSerializer()), + FieldMetadata("publicLeaderboardSubmissionId", "public_leaderboard_submission_id", "_public_leaderboard_submission_id", int, None, PredefinedSerializer(), optional=True), + FieldMetadata("publicLeaderboardScoreFormatted", "public_leaderboard_score_formatted", "_public_leaderboard_score_formatted", str, None, PredefinedSerializer(), optional=True), + FieldMetadata("publicLeaderboardRank", "public_leaderboard_rank", "_public_leaderboard_rank", int, None, PredefinedSerializer(), optional=True), + FieldMetadata("privateLeaderboardSubmissionId", "private_leaderboard_submission_id", "_private_leaderboard_submission_id", int, None, PredefinedSerializer(), optional=True), + FieldMetadata("privateLeaderboardScoreFormatted", "private_leaderboard_score_formatted", "_private_leaderboard_score_formatted", str, None, PredefinedSerializer(), optional=True), + FieldMetadata("privateLeaderboardRank", "private_leaderboard_rank", "_private_leaderboard_rank", int, None, PredefinedSerializer(), optional=True), + FieldMetadata("teamUpEnabled", "team_up_enabled", "_team_up_enabled", bool, False, PredefinedSerializer()), + FieldMetadata("teamUpIntro", "team_up_intro", "_team_up_intro", str, None, PredefinedSerializer(), optional=True), + FieldMetadata("writeUpForumTopicId", "write_up_forum_topic_id", "_write_up_forum_topic_id", int, None, PredefinedSerializer(), optional=True), + FieldMetadata("benchmarkModelVersionId", "benchmark_model_version_id", "_benchmark_model_version_id", int, None, PredefinedSerializer(), optional=True), + FieldMetadata("teamMembers", "team_members", "_team_members", UserAvatar, [], ListSerializer(KaggleObjectSerializer())), +] + +TeamUpInfo._fields = [ + FieldMetadata("enabled", "enabled", "_enabled", bool, False, PredefinedSerializer()), + FieldMetadata("teamLeader", "team_leader", "_team_leader", UserAvatar, None, KaggleObjectSerializer()), + FieldMetadata("intro", "intro", "_intro", str, None, PredefinedSerializer(), optional=True), +] + diff --git a/kagglesdk/datasets/types/dataset_types.py b/kagglesdk/datasets/types/dataset_types.py index 7724c81..36ef0d4 100644 --- a/kagglesdk/datasets/types/dataset_types.py +++ b/kagglesdk/datasets/types/dataset_types.py @@ -1,3 +1,4 @@ +from kagglesdk.common.types.cropped_image_upload import CroppedImageUpload from kagglesdk.kaggle_object import * from kagglesdk.users.types.users_enums import CollaboratorType from typing import Optional, List @@ -78,6 +79,13 @@ class DatasetInfo(KaggleObject): licenses (SettingsLicense) collaborators (DatasetCollaborator) data (DatasetSettingsFile) + expected_update_frequency (str) + Expected update frequency of dataset (see DatasetVersionMetadata). + Accepted values: 'not specified', 'never', 'annually', 'quarterly', + 'monthly', 'weekly', 'daily', 'hourly' + user_specified_sources (str) + User specified sources for current dataset version (see + DatasetVersionMetadata). """ def __init__(self): @@ -96,6 +104,8 @@ def __init__(self): self._licenses = [] self._collaborators = [] self._data = [] + self._expected_update_frequency = None + self._user_specified_sources = None self._freeze() @property @@ -305,6 +315,41 @@ def data(self, data: Optional[List[Optional['DatasetSettingsFile']]]): raise TypeError('data must contain only items of type DatasetSettingsFile') self._data = data + @property + def expected_update_frequency(self) -> str: + r""" + Expected update frequency of dataset (see DatasetVersionMetadata). + Accepted values: 'not specified', 'never', 'annually', 'quarterly', + 'monthly', 'weekly', 'daily', 'hourly' + """ + return self._expected_update_frequency or "" + + @expected_update_frequency.setter + def expected_update_frequency(self, expected_update_frequency: Optional[str]): + if expected_update_frequency is None: + del self.expected_update_frequency + return + if not isinstance(expected_update_frequency, str): + raise TypeError('expected_update_frequency must be of type str') + self._expected_update_frequency = expected_update_frequency + + @property + def user_specified_sources(self) -> str: + r""" + User specified sources for current dataset version (see + DatasetVersionMetadata). + """ + return self._user_specified_sources or "" + + @user_specified_sources.setter + def user_specified_sources(self, user_specified_sources: Optional[str]): + if user_specified_sources is None: + del self.user_specified_sources + return + if not isinstance(user_specified_sources, str): + raise TypeError('user_specified_sources must be of type str') + self._user_specified_sources = user_specified_sources + class DatasetSettings(KaggleObject): r""" @@ -317,6 +362,16 @@ class DatasetSettings(KaggleObject): licenses (SettingsLicense) collaborators (DatasetCollaborator) data (DatasetSettingsFile) + expected_update_frequency (str) + Expected update frequency of dataset (see DatasetVersionMetadata). + Accepted values: 'not specified', 'never', 'annually', 'quarterly', + 'monthly', 'weekly', 'daily', 'hourly' + user_specified_sources (str) + User specified sources for current dataset version (see + DatasetVersionMetadata). + image (CroppedImageUpload) + If provided, will update the dataset image. Expects two crop rectangles + with titles of: 'cover image' and 'thumbnail' """ def __init__(self): @@ -328,6 +383,9 @@ def __init__(self): self._licenses = [] self._collaborators = [] self._data = [] + self._expected_update_frequency = None + self._user_specified_sources = None + self._image = None self._freeze() @property @@ -442,6 +500,58 @@ def data(self, data: Optional[List[Optional['DatasetSettingsFile']]]): raise TypeError('data must contain only items of type DatasetSettingsFile') self._data = data + @property + def expected_update_frequency(self) -> str: + r""" + Expected update frequency of dataset (see DatasetVersionMetadata). + Accepted values: 'not specified', 'never', 'annually', 'quarterly', + 'monthly', 'weekly', 'daily', 'hourly' + """ + return self._expected_update_frequency or "" + + @expected_update_frequency.setter + def expected_update_frequency(self, expected_update_frequency: Optional[str]): + if expected_update_frequency is None: + del self.expected_update_frequency + return + if not isinstance(expected_update_frequency, str): + raise TypeError('expected_update_frequency must be of type str') + self._expected_update_frequency = expected_update_frequency + + @property + def user_specified_sources(self) -> str: + r""" + User specified sources for current dataset version (see + DatasetVersionMetadata). + """ + return self._user_specified_sources or "" + + @user_specified_sources.setter + def user_specified_sources(self, user_specified_sources: Optional[str]): + if user_specified_sources is None: + del self.user_specified_sources + return + if not isinstance(user_specified_sources, str): + raise TypeError('user_specified_sources must be of type str') + self._user_specified_sources = user_specified_sources + + @property + def image(self) -> Optional['CroppedImageUpload']: + r""" + If provided, will update the dataset image. Expects two crop rectangles + with titles of: 'cover image' and 'thumbnail' + """ + return self._image or None + + @image.setter + def image(self, image: Optional[Optional['CroppedImageUpload']]): + if image is None: + del self.image + return + if not isinstance(image, CroppedImageUpload): + raise TypeError('image must be of type CroppedImageUpload') + self._image = image + class DatasetSettingsFile(KaggleObject): r""" @@ -614,6 +724,8 @@ def name(self, name: Optional[str]): FieldMetadata("licenses", "licenses", "_licenses", SettingsLicense, [], ListSerializer(KaggleObjectSerializer())), FieldMetadata("collaborators", "collaborators", "_collaborators", DatasetCollaborator, [], ListSerializer(KaggleObjectSerializer())), FieldMetadata("data", "data", "_data", DatasetSettingsFile, [], ListSerializer(KaggleObjectSerializer())), + FieldMetadata("expectedUpdateFrequency", "expected_update_frequency", "_expected_update_frequency", str, None, PredefinedSerializer(), optional=True), + FieldMetadata("userSpecifiedSources", "user_specified_sources", "_user_specified_sources", str, None, PredefinedSerializer(), optional=True), ] DatasetSettings._fields = [ @@ -625,6 +737,9 @@ def name(self, name: Optional[str]): FieldMetadata("licenses", "licenses", "_licenses", SettingsLicense, [], ListSerializer(KaggleObjectSerializer())), FieldMetadata("collaborators", "collaborators", "_collaborators", DatasetCollaborator, [], ListSerializer(KaggleObjectSerializer())), FieldMetadata("data", "data", "_data", DatasetSettingsFile, [], ListSerializer(KaggleObjectSerializer())), + FieldMetadata("expectedUpdateFrequency", "expected_update_frequency", "_expected_update_frequency", str, None, PredefinedSerializer(), optional=True), + FieldMetadata("userSpecifiedSources", "user_specified_sources", "_user_specified_sources", str, None, PredefinedSerializer(), optional=True), + FieldMetadata("image", "image", "_image", CroppedImageUpload, None, KaggleObjectSerializer(), optional=True), ] DatasetSettingsFile._fields = [ diff --git a/kagglesdk/discussions/types/discussions_enums.py b/kagglesdk/discussions/types/discussions_enums.py new file mode 100644 index 0000000..e01c637 --- /dev/null +++ b/kagglesdk/discussions/types/discussions_enums.py @@ -0,0 +1,30 @@ +import enum + +class CommentAuthorType(enum.Enum): + COMMENT_AUTHOR_TYPE_UNSPECIFIED = 0 + r""" + Default value of author type makes no claim about what type of author it + is, and nothing special should be shown. + """ + HOST = 1 + DATASET_CREATOR = 2 + TOPIC = 3 + COMMENT = 4 + ADMIN = 5 + MODEL_CREATOR = 6 + JUDGE = 7 + +class EmojiReaction(enum.Enum): + EMOJI_REACTION_UNSPECIFIED = 0 + THANK_YOU = 1 + YAY = 2 + LOVE = 3 + KAGGLE = 4 + FUNNY = 5 + SURPRISE = 6 + +class FollowUpStatus(enum.Enum): + NONE = 0 + IN_PROGRESS = 1 + DONE = 2 + diff --git a/kagglesdk/discussions/types/feedback_tracking_data.py b/kagglesdk/discussions/types/feedback_tracking_data.py new file mode 100644 index 0000000..20ef673 --- /dev/null +++ b/kagglesdk/discussions/types/feedback_tracking_data.py @@ -0,0 +1,52 @@ +from kagglesdk.discussions.types.discussions_enums import FollowUpStatus +from kagglesdk.kaggle_object import * +from typing import Optional + +class FeedbackTrackingData(KaggleObject): + r""" + This is serialized/deserialized to the database using JsonConvert. Ensure + backward compatibility with existing data when adding/removing/changing + fields. + + Attributes: + buganizer_id (int) + follow_up_status (FollowUpStatus) + """ + + def __init__(self): + self._buganizer_id = None + self._follow_up_status = FollowUpStatus.NONE + self._freeze() + + @property + def buganizer_id(self) -> int: + return self._buganizer_id or 0 + + @buganizer_id.setter + def buganizer_id(self, buganizer_id: Optional[int]): + if buganizer_id is None: + del self.buganizer_id + return + if not isinstance(buganizer_id, int): + raise TypeError('buganizer_id must be of type int') + self._buganizer_id = buganizer_id + + @property + def follow_up_status(self) -> 'FollowUpStatus': + return self._follow_up_status + + @follow_up_status.setter + def follow_up_status(self, follow_up_status: 'FollowUpStatus'): + if follow_up_status is None: + del self.follow_up_status + return + if not isinstance(follow_up_status, FollowUpStatus): + raise TypeError('follow_up_status must be of type FollowUpStatus') + self._follow_up_status = follow_up_status + + +FeedbackTrackingData._fields = [ + FieldMetadata("buganizerId", "buganizer_id", "_buganizer_id", int, None, PredefinedSerializer(), optional=True), + FieldMetadata("followUpStatus", "follow_up_status", "_follow_up_status", FollowUpStatus, FollowUpStatus.NONE, EnumSerializer()), +] + diff --git a/kagglesdk/discussions/types/forum_message.py b/kagglesdk/discussions/types/forum_message.py new file mode 100644 index 0000000..368fe50 --- /dev/null +++ b/kagglesdk/discussions/types/forum_message.py @@ -0,0 +1,880 @@ +from datetime import datetime +from kagglesdk.abuse.types.abuse_enums import PrivatedModerationStatus +from kagglesdk.competitions.types.team import TeamUpInfo +from kagglesdk.discussions.types.discussions_enums import CommentAuthorType, EmojiReaction +from kagglesdk.discussions.types.feedback_tracking_data import FeedbackTrackingData +from kagglesdk.kaggle_object import * +from kagglesdk.users.types.user_avatar import UserAvatar +from typing import Optional, List + +class CommentAttachment(KaggleObject): + r""" + Attributes: + file_type (str) + id (int) + name (str) + total_bytes (int) + url (str) + blob_token (str) + """ + + def __init__(self): + self._file_type = None + self._id = 0 + self._name = "" + self._total_bytes = 0 + self._url = None + self._blob_token = None + self._freeze() + + @property + def file_type(self) -> str: + return self._file_type or "" + + @file_type.setter + def file_type(self, file_type: Optional[str]): + if file_type is None: + del self.file_type + return + if not isinstance(file_type, str): + raise TypeError('file_type must be of type str') + self._file_type = file_type + + @property + def id(self) -> int: + 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 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 total_bytes(self) -> int: + return self._total_bytes + + @total_bytes.setter + def total_bytes(self, total_bytes: int): + if total_bytes is None: + del self.total_bytes + return + if not isinstance(total_bytes, int): + raise TypeError('total_bytes must be of type int') + self._total_bytes = total_bytes + + @property + def url(self) -> str: + return self._url or "" + + @url.setter + def url(self, url: Optional[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 + + @property + def blob_token(self) -> str: + return self._blob_token or "" + + @blob_token.setter + def blob_token(self, blob_token: Optional[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 + + +class CommentForumMessage(KaggleObject): + r""" + This is a version of ForumMessage meant for displaying comments + + Attributes: + id (int) + post_date (datetime) + raw_markdown (str) + content (str) + replies (CommentForumMessage) + attachments (CommentAttachment) + parent (DiscussionItemLink) + author (UserAvatar) + author_type (CommentAuthorType) + votes (CommentVoteButton) + can_delete (bool) + Permissions/Display + is_user_author (bool) + has_flags (bool) + is_deleted (bool) + is_admin_deleted (bool) + is_flagged (bool) + is_spammed (bool) + current_kernel_version (int) + kernel_version (int) + competition_ranking (int) + Rankings + feedback_tracking_data (FeedbackTrackingData) + is_pinned (bool) + is_auto_privated (bool) + moderation_status (PrivatedModerationStatus) + is_thank_you (bool) + is_collapsed (bool) + True if the comment should be collapsed into its parent (ie 'show X more + replies'). Used by FE, populated by BE. + is_partial (bool) + True if the data is only partially populated. Clients should call + BatchGetForumMessages if they want more fields. Fields Included: Id, + IsPinned, IsDeleted, PostDate, IsThankYou, Votes + reactions (ForumMessageReactionGroup) + List of reactions to the message, grouped by the reaction type. + team_up_info (TeamUpInfo) + Competitions team up info for the comment's author + """ + + def __init__(self): + self._id = 0 + self._post_date = None + self._raw_markdown = None + self._content = "" + self._replies = [] + self._attachments = [] + self._parent = None + self._author = None + self._author_type = CommentAuthorType.COMMENT_AUTHOR_TYPE_UNSPECIFIED + self._votes = None + self._can_delete = False + self._is_user_author = False + self._has_flags = False + self._is_deleted = False + self._is_admin_deleted = False + self._is_flagged = False + self._is_spammed = False + self._current_kernel_version = 0 + self._kernel_version = None + self._competition_ranking = None + self._feedback_tracking_data = None + self._is_pinned = False + self._is_auto_privated = False + self._moderation_status = PrivatedModerationStatus.PRIVATED_MODERATION_STATUS_UNSPECIFIED + self._is_thank_you = None + self._is_collapsed = False + self._is_partial = False + self._reactions = [] + self._team_up_info = None + self._freeze() + + @property + def id(self) -> int: + 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 post_date(self) -> datetime: + return self._post_date + + @post_date.setter + def post_date(self, post_date: datetime): + if post_date is None: + del self.post_date + return + if not isinstance(post_date, datetime): + raise TypeError('post_date must be of type datetime') + self._post_date = post_date + + @property + def raw_markdown(self) -> str: + return self._raw_markdown or "" + + @raw_markdown.setter + def raw_markdown(self, raw_markdown: Optional[str]): + if raw_markdown is None: + del self.raw_markdown + return + if not isinstance(raw_markdown, str): + raise TypeError('raw_markdown must be of type str') + self._raw_markdown = raw_markdown + + @property + def content(self) -> str: + return self._content + + @content.setter + def content(self, content: str): + if content is None: + del self.content + return + if not isinstance(content, str): + raise TypeError('content must be of type str') + self._content = content + + @property + def replies(self) -> Optional[List[Optional['CommentForumMessage']]]: + return self._replies + + @replies.setter + def replies(self, replies: Optional[List[Optional['CommentForumMessage']]]): + if replies is None: + del self.replies + return + if not isinstance(replies, list): + raise TypeError('replies must be of type list') + if not all([isinstance(t, CommentForumMessage) for t in replies]): + raise TypeError('replies must contain only items of type CommentForumMessage') + self._replies = replies + + @property + def attachments(self) -> Optional[List[Optional['CommentAttachment']]]: + return self._attachments + + @attachments.setter + def attachments(self, attachments: Optional[List[Optional['CommentAttachment']]]): + if attachments is None: + del self.attachments + return + if not isinstance(attachments, list): + raise TypeError('attachments must be of type list') + if not all([isinstance(t, CommentAttachment) for t in attachments]): + raise TypeError('attachments must contain only items of type CommentAttachment') + self._attachments = attachments + + @property + def parent(self) -> Optional['DiscussionItemLink']: + return self._parent + + @parent.setter + def parent(self, parent: Optional['DiscussionItemLink']): + if parent is None: + del self.parent + return + if not isinstance(parent, DiscussionItemLink): + raise TypeError('parent must be of type DiscussionItemLink') + self._parent = parent + + @property + def author(self) -> Optional['UserAvatar']: + return self._author + + @author.setter + def author(self, author: Optional['UserAvatar']): + if author is None: + del self.author + return + if not isinstance(author, UserAvatar): + raise TypeError('author must be of type UserAvatar') + self._author = author + + @property + def author_type(self) -> 'CommentAuthorType': + return self._author_type + + @author_type.setter + def author_type(self, author_type: 'CommentAuthorType'): + if author_type is None: + del self.author_type + return + if not isinstance(author_type, CommentAuthorType): + raise TypeError('author_type must be of type CommentAuthorType') + self._author_type = author_type + + @property + def votes(self) -> Optional['CommentVoteButton']: + return self._votes + + @votes.setter + def votes(self, votes: Optional['CommentVoteButton']): + if votes is None: + del self.votes + return + if not isinstance(votes, CommentVoteButton): + raise TypeError('votes must be of type CommentVoteButton') + self._votes = votes + + @property + def can_delete(self) -> bool: + """Permissions/Display""" + return self._can_delete + + @can_delete.setter + def can_delete(self, can_delete: bool): + if can_delete is None: + del self.can_delete + return + if not isinstance(can_delete, bool): + raise TypeError('can_delete must be of type bool') + self._can_delete = can_delete + + @property + def is_user_author(self) -> bool: + return self._is_user_author + + @is_user_author.setter + def is_user_author(self, is_user_author: bool): + if is_user_author is None: + del self.is_user_author + return + if not isinstance(is_user_author, bool): + raise TypeError('is_user_author must be of type bool') + self._is_user_author = is_user_author + + @property + def has_flags(self) -> bool: + return self._has_flags + + @has_flags.setter + def has_flags(self, has_flags: bool): + if has_flags is None: + del self.has_flags + return + if not isinstance(has_flags, bool): + raise TypeError('has_flags must be of type bool') + self._has_flags = has_flags + + @property + def is_deleted(self) -> bool: + return self._is_deleted + + @is_deleted.setter + def is_deleted(self, is_deleted: bool): + if is_deleted is None: + del self.is_deleted + return + if not isinstance(is_deleted, bool): + raise TypeError('is_deleted must be of type bool') + self._is_deleted = is_deleted + + @property + def is_admin_deleted(self) -> bool: + return self._is_admin_deleted + + @is_admin_deleted.setter + def is_admin_deleted(self, is_admin_deleted: bool): + if is_admin_deleted is None: + del self.is_admin_deleted + return + if not isinstance(is_admin_deleted, bool): + raise TypeError('is_admin_deleted must be of type bool') + self._is_admin_deleted = is_admin_deleted + + @property + def is_flagged(self) -> bool: + return self._is_flagged + + @is_flagged.setter + def is_flagged(self, is_flagged: bool): + if is_flagged is None: + del self.is_flagged + return + if not isinstance(is_flagged, bool): + raise TypeError('is_flagged must be of type bool') + self._is_flagged = is_flagged + + @property + def is_spammed(self) -> bool: + return self._is_spammed + + @is_spammed.setter + def is_spammed(self, is_spammed: bool): + if is_spammed is None: + del self.is_spammed + return + if not isinstance(is_spammed, bool): + raise TypeError('is_spammed must be of type bool') + self._is_spammed = is_spammed + + @property + def current_kernel_version(self) -> int: + return self._current_kernel_version + + @current_kernel_version.setter + def current_kernel_version(self, current_kernel_version: int): + if current_kernel_version is None: + del self.current_kernel_version + return + if not isinstance(current_kernel_version, int): + raise TypeError('current_kernel_version must be of type int') + self._current_kernel_version = current_kernel_version + + @property + def is_pinned(self) -> bool: + return self._is_pinned + + @is_pinned.setter + def is_pinned(self, is_pinned: bool): + if is_pinned is None: + del self.is_pinned + return + if not isinstance(is_pinned, bool): + raise TypeError('is_pinned must be of type bool') + self._is_pinned = is_pinned + + @property + def is_auto_privated(self) -> bool: + return self._is_auto_privated + + @is_auto_privated.setter + def is_auto_privated(self, is_auto_privated: bool): + if is_auto_privated is None: + del self.is_auto_privated + return + if not isinstance(is_auto_privated, bool): + raise TypeError('is_auto_privated must be of type bool') + self._is_auto_privated = is_auto_privated + + @property + def is_thank_you(self) -> bool: + return self._is_thank_you or False + + @is_thank_you.setter + def is_thank_you(self, is_thank_you: Optional[bool]): + if is_thank_you is None: + del self.is_thank_you + return + if not isinstance(is_thank_you, bool): + raise TypeError('is_thank_you must be of type bool') + self._is_thank_you = is_thank_you + + @property + def kernel_version(self) -> int: + return self._kernel_version or 0 + + @kernel_version.setter + def kernel_version(self, kernel_version: Optional[int]): + if kernel_version is None: + del self.kernel_version + return + if not isinstance(kernel_version, int): + raise TypeError('kernel_version must be of type int') + self._kernel_version = kernel_version + + @property + def competition_ranking(self) -> int: + """Rankings""" + return self._competition_ranking or 0 + + @competition_ranking.setter + def competition_ranking(self, competition_ranking: Optional[int]): + if competition_ranking is None: + del self.competition_ranking + return + if not isinstance(competition_ranking, int): + raise TypeError('competition_ranking must be of type int') + self._competition_ranking = competition_ranking + + @property + def feedback_tracking_data(self) -> Optional['FeedbackTrackingData']: + return self._feedback_tracking_data + + @feedback_tracking_data.setter + def feedback_tracking_data(self, feedback_tracking_data: Optional['FeedbackTrackingData']): + if feedback_tracking_data is None: + del self.feedback_tracking_data + return + if not isinstance(feedback_tracking_data, FeedbackTrackingData): + raise TypeError('feedback_tracking_data must be of type FeedbackTrackingData') + self._feedback_tracking_data = feedback_tracking_data + + @property + def moderation_status(self) -> 'PrivatedModerationStatus': + return self._moderation_status + + @moderation_status.setter + def moderation_status(self, moderation_status: 'PrivatedModerationStatus'): + if moderation_status is None: + del self.moderation_status + return + if not isinstance(moderation_status, PrivatedModerationStatus): + raise TypeError('moderation_status must be of type PrivatedModerationStatus') + self._moderation_status = moderation_status + + @property + def is_collapsed(self) -> bool: + r""" + True if the comment should be collapsed into its parent (ie 'show X more + replies'). Used by FE, populated by BE. + """ + return self._is_collapsed + + @is_collapsed.setter + def is_collapsed(self, is_collapsed: bool): + if is_collapsed is None: + del self.is_collapsed + return + if not isinstance(is_collapsed, bool): + raise TypeError('is_collapsed must be of type bool') + self._is_collapsed = is_collapsed + + @property + def is_partial(self) -> bool: + r""" + True if the data is only partially populated. Clients should call + BatchGetForumMessages if they want more fields. Fields Included: Id, + IsPinned, IsDeleted, PostDate, IsThankYou, Votes + """ + return self._is_partial + + @is_partial.setter + def is_partial(self, is_partial: bool): + if is_partial is None: + del self.is_partial + return + if not isinstance(is_partial, bool): + raise TypeError('is_partial must be of type bool') + self._is_partial = is_partial + + @property + def reactions(self) -> Optional[List[Optional['ForumMessageReactionGroup']]]: + """List of reactions to the message, grouped by the reaction type.""" + return self._reactions + + @reactions.setter + def reactions(self, reactions: Optional[List[Optional['ForumMessageReactionGroup']]]): + if reactions is None: + del self.reactions + return + if not isinstance(reactions, list): + raise TypeError('reactions must be of type list') + if not all([isinstance(t, ForumMessageReactionGroup) for t in reactions]): + raise TypeError('reactions must contain only items of type ForumMessageReactionGroup') + self._reactions = reactions + + @property + def team_up_info(self) -> Optional['TeamUpInfo']: + """Competitions team up info for the comment's author""" + return self._team_up_info + + @team_up_info.setter + def team_up_info(self, team_up_info: Optional['TeamUpInfo']): + if team_up_info is None: + del self.team_up_info + return + if not isinstance(team_up_info, TeamUpInfo): + raise TypeError('team_up_info must be of type TeamUpInfo') + self._team_up_info = team_up_info + + +class CommentVoteButton(KaggleObject): + r""" + Attributes: + total_votes (int) + Count of total votes (up+down). + has_already_voted_up (bool) + has_already_voted_down (bool) + can_upvote (bool) + can_downvote (bool) + total_upvotes (int) + Count of upvotes only (note downvotes is missing since it can be + calculated). + """ + + def __init__(self): + self._total_votes = 0 + self._has_already_voted_up = False + self._has_already_voted_down = False + self._can_upvote = False + self._can_downvote = False + self._total_upvotes = 0 + self._freeze() + + @property + def total_votes(self) -> int: + """Count of total votes (up+down).""" + return self._total_votes + + @total_votes.setter + def total_votes(self, total_votes: int): + if total_votes is None: + del self.total_votes + return + if not isinstance(total_votes, int): + raise TypeError('total_votes must be of type int') + self._total_votes = total_votes + + @property + def total_upvotes(self) -> int: + r""" + Count of upvotes only (note downvotes is missing since it can be + calculated). + """ + return self._total_upvotes + + @total_upvotes.setter + def total_upvotes(self, total_upvotes: int): + if total_upvotes is None: + del self.total_upvotes + return + if not isinstance(total_upvotes, int): + raise TypeError('total_upvotes must be of type int') + self._total_upvotes = total_upvotes + + @property + def has_already_voted_up(self) -> bool: + return self._has_already_voted_up + + @has_already_voted_up.setter + def has_already_voted_up(self, has_already_voted_up: bool): + if has_already_voted_up is None: + del self.has_already_voted_up + return + if not isinstance(has_already_voted_up, bool): + raise TypeError('has_already_voted_up must be of type bool') + self._has_already_voted_up = has_already_voted_up + + @property + def has_already_voted_down(self) -> bool: + return self._has_already_voted_down + + @has_already_voted_down.setter + def has_already_voted_down(self, has_already_voted_down: bool): + if has_already_voted_down is None: + del self.has_already_voted_down + return + if not isinstance(has_already_voted_down, bool): + raise TypeError('has_already_voted_down must be of type bool') + self._has_already_voted_down = has_already_voted_down + + @property + def can_upvote(self) -> bool: + return self._can_upvote + + @can_upvote.setter + def can_upvote(self, can_upvote: bool): + if can_upvote is None: + del self.can_upvote + return + if not isinstance(can_upvote, bool): + raise TypeError('can_upvote must be of type bool') + self._can_upvote = can_upvote + + @property + def can_downvote(self) -> bool: + return self._can_downvote + + @can_downvote.setter + def can_downvote(self, can_downvote: bool): + if can_downvote is None: + del self.can_downvote + return + if not isinstance(can_downvote, bool): + raise TypeError('can_downvote must be of type bool') + self._can_downvote = can_downvote + + +class DiscussionItemLink(KaggleObject): + r""" + Used to store data about a related item which we'll want to link to. + Eg a message's topic, or a message's script. + + Attributes: + id (int) + name (str) + url (str) + """ + + def __init__(self): + self._id = 0 + self._name = None + self._url = None + self._freeze() + + @property + def id(self) -> int: + 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 name(self) -> str: + return self._name or "" + + @name.setter + def name(self, name: Optional[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 url(self) -> str: + return self._url or "" + + @url.setter + def url(self, url: Optional[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 ForumMessageReactionGroup(KaggleObject): + r""" + A particular reaction to a forum message (ie grouped by emoji). + + Attributes: + emoji (EmojiReaction) + Which reaction it is + featured_user_names (str) + Users who've reacted. May be truncated, but will always include the current + user if they've reacted. + user_count (int) + The total number of users who've reacted (including any not included in + usernames). + """ + + def __init__(self): + self._emoji = EmojiReaction.EMOJI_REACTION_UNSPECIFIED + self._featured_user_names = [] + self._user_count = 0 + self._freeze() + + @property + def emoji(self) -> 'EmojiReaction': + """Which reaction it is""" + return self._emoji + + @emoji.setter + def emoji(self, emoji: 'EmojiReaction'): + if emoji is None: + del self.emoji + return + if not isinstance(emoji, EmojiReaction): + raise TypeError('emoji must be of type EmojiReaction') + self._emoji = emoji + + @property + def featured_user_names(self) -> Optional[List[str]]: + r""" + Users who've reacted. May be truncated, but will always include the current + user if they've reacted. + """ + return self._featured_user_names + + @featured_user_names.setter + def featured_user_names(self, featured_user_names: Optional[List[str]]): + if featured_user_names is None: + del self.featured_user_names + return + if not isinstance(featured_user_names, list): + raise TypeError('featured_user_names must be of type list') + if not all([isinstance(t, str) for t in featured_user_names]): + raise TypeError('featured_user_names must contain only items of type str') + self._featured_user_names = featured_user_names + + @property + def user_count(self) -> int: + r""" + The total number of users who've reacted (including any not included in + usernames). + """ + return self._user_count + + @user_count.setter + def user_count(self, user_count: int): + if user_count is None: + del self.user_count + return + if not isinstance(user_count, int): + raise TypeError('user_count must be of type int') + self._user_count = user_count + + +CommentAttachment._fields = [ + FieldMetadata("fileType", "file_type", "_file_type", str, None, PredefinedSerializer(), optional=True), + FieldMetadata("id", "id", "_id", int, 0, PredefinedSerializer()), + FieldMetadata("name", "name", "_name", str, "", PredefinedSerializer()), + FieldMetadata("totalBytes", "total_bytes", "_total_bytes", int, 0, PredefinedSerializer()), + FieldMetadata("url", "url", "_url", str, None, PredefinedSerializer(), optional=True), + FieldMetadata("blobToken", "blob_token", "_blob_token", str, None, PredefinedSerializer(), optional=True), +] + +CommentForumMessage._fields = [ + FieldMetadata("id", "id", "_id", int, 0, PredefinedSerializer()), + FieldMetadata("postDate", "post_date", "_post_date", datetime, None, DateTimeSerializer()), + FieldMetadata("rawMarkdown", "raw_markdown", "_raw_markdown", str, None, PredefinedSerializer(), optional=True), + FieldMetadata("content", "content", "_content", str, "", PredefinedSerializer()), + FieldMetadata("replies", "replies", "_replies", CommentForumMessage, [], ListSerializer(KaggleObjectSerializer())), + FieldMetadata("attachments", "attachments", "_attachments", CommentAttachment, [], ListSerializer(KaggleObjectSerializer())), + FieldMetadata("parent", "parent", "_parent", DiscussionItemLink, None, KaggleObjectSerializer()), + FieldMetadata("author", "author", "_author", UserAvatar, None, KaggleObjectSerializer()), + FieldMetadata("authorType", "author_type", "_author_type", CommentAuthorType, CommentAuthorType.COMMENT_AUTHOR_TYPE_UNSPECIFIED, EnumSerializer()), + FieldMetadata("votes", "votes", "_votes", CommentVoteButton, None, KaggleObjectSerializer()), + FieldMetadata("canDelete", "can_delete", "_can_delete", bool, False, PredefinedSerializer()), + FieldMetadata("isUserAuthor", "is_user_author", "_is_user_author", bool, False, PredefinedSerializer()), + FieldMetadata("hasFlags", "has_flags", "_has_flags", bool, False, PredefinedSerializer()), + FieldMetadata("isDeleted", "is_deleted", "_is_deleted", bool, False, PredefinedSerializer()), + FieldMetadata("isAdminDeleted", "is_admin_deleted", "_is_admin_deleted", bool, False, PredefinedSerializer()), + FieldMetadata("isFlagged", "is_flagged", "_is_flagged", bool, False, PredefinedSerializer()), + FieldMetadata("isSpammed", "is_spammed", "_is_spammed", bool, False, PredefinedSerializer()), + FieldMetadata("currentKernelVersion", "current_kernel_version", "_current_kernel_version", int, 0, PredefinedSerializer()), + FieldMetadata("kernelVersion", "kernel_version", "_kernel_version", int, None, PredefinedSerializer(), optional=True), + FieldMetadata("competitionRanking", "competition_ranking", "_competition_ranking", int, None, PredefinedSerializer(), optional=True), + FieldMetadata("feedbackTrackingData", "feedback_tracking_data", "_feedback_tracking_data", FeedbackTrackingData, None, KaggleObjectSerializer()), + FieldMetadata("isPinned", "is_pinned", "_is_pinned", bool, False, PredefinedSerializer()), + FieldMetadata("isAutoPrivated", "is_auto_privated", "_is_auto_privated", bool, False, PredefinedSerializer()), + FieldMetadata("moderationStatus", "moderation_status", "_moderation_status", PrivatedModerationStatus, PrivatedModerationStatus.PRIVATED_MODERATION_STATUS_UNSPECIFIED, EnumSerializer()), + FieldMetadata("isThankYou", "is_thank_you", "_is_thank_you", bool, None, PredefinedSerializer(), optional=True), + FieldMetadata("isCollapsed", "is_collapsed", "_is_collapsed", bool, False, PredefinedSerializer()), + FieldMetadata("isPartial", "is_partial", "_is_partial", bool, False, PredefinedSerializer()), + FieldMetadata("reactions", "reactions", "_reactions", ForumMessageReactionGroup, [], ListSerializer(KaggleObjectSerializer())), + FieldMetadata("teamUpInfo", "team_up_info", "_team_up_info", TeamUpInfo, None, KaggleObjectSerializer()), +] + +CommentVoteButton._fields = [ + FieldMetadata("totalVotes", "total_votes", "_total_votes", int, 0, PredefinedSerializer()), + FieldMetadata("hasAlreadyVotedUp", "has_already_voted_up", "_has_already_voted_up", bool, False, PredefinedSerializer()), + FieldMetadata("hasAlreadyVotedDown", "has_already_voted_down", "_has_already_voted_down", bool, False, PredefinedSerializer()), + FieldMetadata("canUpvote", "can_upvote", "_can_upvote", bool, False, PredefinedSerializer()), + FieldMetadata("canDownvote", "can_downvote", "_can_downvote", bool, False, PredefinedSerializer()), + FieldMetadata("totalUpvotes", "total_upvotes", "_total_upvotes", int, 0, PredefinedSerializer()), +] + +DiscussionItemLink._fields = [ + FieldMetadata("id", "id", "_id", int, 0, PredefinedSerializer()), + FieldMetadata("name", "name", "_name", str, None, PredefinedSerializer(), optional=True), + FieldMetadata("url", "url", "_url", str, None, PredefinedSerializer(), optional=True), +] + +ForumMessageReactionGroup._fields = [ + FieldMetadata("emoji", "emoji", "_emoji", EmojiReaction, EmojiReaction.EMOJI_REACTION_UNSPECIFIED, EnumSerializer()), + FieldMetadata("featuredUserNames", "featured_user_names", "_featured_user_names", str, [], ListSerializer(PredefinedSerializer())), + FieldMetadata("userCount", "user_count", "_user_count", int, 0, PredefinedSerializer()), +] + diff --git a/kagglesdk/discussions/types/writeup_enums.py b/kagglesdk/discussions/types/writeup_enums.py index 5778532..d4473c9 100644 --- a/kagglesdk/discussions/types/writeup_enums.py +++ b/kagglesdk/discussions/types/writeup_enums.py @@ -1,5 +1,15 @@ import enum +class WriteUpLinkLocation(enum.Enum): + WRITE_UP_LINK_LOCATION_UNSPECIFIED = 0 + ADDITIONAL_LINKS = 1 + CAROUSEL = 2 + +class WriteUpLinkMediaType(enum.Enum): + WRITE_UP_LINK_MEDIA_TYPE_UNSPECIFIED = 0 + IMAGE = 1 + VIDEO = 2 + class WriteUpType(enum.Enum): WRITE_UP_TYPE_UNSPECIFIED = 0 HACKATHON_PROJECT = 1 diff --git a/kagglesdk/discussions/types/writeup_types.py b/kagglesdk/discussions/types/writeup_types.py new file mode 100644 index 0000000..48176be --- /dev/null +++ b/kagglesdk/discussions/types/writeup_types.py @@ -0,0 +1,1133 @@ +from datetime import datetime +from kagglesdk.common.types.cropped_image_upload import CroppedImageUpload +from kagglesdk.community.types.content_enums import ContentState +from kagglesdk.discussions.types.forum_message import CommentForumMessage +from kagglesdk.discussions.types.writeup_enums import WriteUpLinkLocation, WriteUpLinkMediaType, WriteUpType +from kagglesdk.kaggle_object import * +from kagglesdk.licenses.types.licenses_types import License +from kagglesdk.security.types.security_types import KaggleResourceType +from kagglesdk.tags.types.tag_service import Tag +from kagglesdk.users.types.legacy_organizations_service import OrganizationCard +from kagglesdk.users.types.progression_service import Medal +from kagglesdk.users.types.user_avatar import UserAvatar +from typing import Optional, List + +class WriteUp(KaggleObject): + r""" + Attributes: + id (int) + Id of the WriteUp + topic_id (int) + FK of ForumTopic + title (str) + Title of the WriteUp + subtitle (str) + Subtitle of the WriteUp + message (CommentForumMessage) + Message of the WriteUp + type (WriteUpType) + Type of WriteUp used for different contexts (i.e. competition vs hackathon + WriteUp) + cover_image_url (str) + Url of banner image to appear at the top of the WriteUp + write_up_links (WriteUpLink) + List of all links included in the WriteUp + tags (Tag) + List of tags connected to the WriteUp + slug (str) + Unique path name for clean URLs + url (str) + On-the-fly created URL pointing to the WriteUp based on the slug + create_time (datetime) + Time when WriteUp was created + update_time (datetime) + Time when WriteUp was last updated + can_edit (bool) + Indicates whether the requesting user has permission to edit the WriteUp + can_delete (bool) + Indicates whether the requesting user has permission to delete the WriteUp + content_state (ContentState) + Represents the content state of the WriteUp + is_spammed (bool) + Indicates whether the WriteUp has been marked as spam by moderation + license (License) + The license that applies to the WriteUp + authors (str) + Comma-separated list of the authors of the WriteUp + thumbnail_image_url (str) + Url of thumbnail image to represent the WriteUp + original_image_url (str) + Url of original image that's used by the cover and thumbnail image + image_info (WriteUpImageInfo) + Crop settings for cover and thumbnail images + can_pin (bool) + Indicates whether the requesting user can pin the WriteUp to their profile + collaborators (UserAvatar) + Collaborators on Competition or Hackathon WriteUp, i.e. team members in a + hackathon competition + publish_time (datetime) + Time when WriteUp was last published + """ + + def __init__(self): + self._id = 0 + self._topic_id = 0 + self._title = "" + self._subtitle = "" + self._message = None + self._type = WriteUpType.WRITE_UP_TYPE_UNSPECIFIED + self._cover_image_url = "" + self._write_up_links = [] + self._tags = [] + self._slug = "" + self._url = "" + self._create_time = None + self._update_time = None + self._can_edit = False + self._can_delete = False + self._content_state = ContentState.CONTENT_STATE_UNSPECIFIED + self._is_spammed = False + self._license = None + self._authors = None + self._thumbnail_image_url = "" + self._original_image_url = "" + self._image_info = None + self._can_pin = False + self._collaborators = [] + self._publish_time = None + self._freeze() + + @property + def id(self) -> int: + """Id of the WriteUp""" + 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 topic_id(self) -> int: + """FK of ForumTopic""" + return self._topic_id + + @topic_id.setter + def topic_id(self, topic_id: int): + if topic_id is None: + del self.topic_id + return + if not isinstance(topic_id, int): + raise TypeError('topic_id must be of type int') + self._topic_id = topic_id + + @property + def title(self) -> str: + """Title of the WriteUp""" + 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 subtitle(self) -> str: + """Subtitle of the WriteUp""" + return self._subtitle + + @subtitle.setter + def subtitle(self, subtitle: str): + if subtitle is None: + del self.subtitle + return + if not isinstance(subtitle, str): + raise TypeError('subtitle must be of type str') + self._subtitle = subtitle + + @property + def message(self) -> Optional['CommentForumMessage']: + """Message of the WriteUp""" + return self._message + + @message.setter + def message(self, message: Optional['CommentForumMessage']): + if message is None: + del self.message + return + if not isinstance(message, CommentForumMessage): + raise TypeError('message must be of type CommentForumMessage') + self._message = message + + @property + def type(self) -> 'WriteUpType': + r""" + Type of WriteUp used for different contexts (i.e. competition vs hackathon + WriteUp) + """ + return self._type + + @type.setter + def type(self, type: 'WriteUpType'): + if type is None: + del self.type + return + if not isinstance(type, WriteUpType): + raise TypeError('type must be of type WriteUpType') + self._type = type + + @property + def cover_image_url(self) -> str: + """Url of banner image to appear at the top of the WriteUp""" + return self._cover_image_url + + @cover_image_url.setter + def cover_image_url(self, cover_image_url: str): + if cover_image_url is None: + del self.cover_image_url + return + if not isinstance(cover_image_url, str): + raise TypeError('cover_image_url must be of type str') + self._cover_image_url = cover_image_url + + @property + def write_up_links(self) -> Optional[List[Optional['WriteUpLink']]]: + """List of all links included in the WriteUp""" + return self._write_up_links + + @write_up_links.setter + def write_up_links(self, write_up_links: Optional[List[Optional['WriteUpLink']]]): + if write_up_links is None: + del self.write_up_links + return + if not isinstance(write_up_links, list): + raise TypeError('write_up_links must be of type list') + if not all([isinstance(t, WriteUpLink) for t in write_up_links]): + raise TypeError('write_up_links must contain only items of type WriteUpLink') + self._write_up_links = write_up_links + + @property + def tags(self) -> Optional[List[Optional['Tag']]]: + """List of tags connected to the WriteUp""" + return self._tags + + @tags.setter + def tags(self, tags: Optional[List[Optional['Tag']]]): + 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, Tag) for t in tags]): + raise TypeError('tags must contain only items of type Tag') + self._tags = tags + + @property + def slug(self) -> str: + """Unique path name for clean URLs""" + return self._slug + + @slug.setter + def slug(self, slug: str): + if slug is None: + del self.slug + return + if not isinstance(slug, str): + raise TypeError('slug must be of type str') + self._slug = slug + + @property + def url(self) -> str: + """On-the-fly created URL pointing to the WriteUp based on the slug""" + 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 + + @property + def create_time(self) -> datetime: + """Time when WriteUp was created""" + return self._create_time + + @create_time.setter + def create_time(self, create_time: datetime): + if create_time is None: + del self.create_time + return + if not isinstance(create_time, datetime): + raise TypeError('create_time must be of type datetime') + self._create_time = create_time + + @property + def update_time(self) -> datetime: + """Time when WriteUp was last updated""" + return self._update_time + + @update_time.setter + def update_time(self, update_time: datetime): + if update_time is None: + del self.update_time + return + if not isinstance(update_time, datetime): + raise TypeError('update_time must be of type datetime') + self._update_time = update_time + + @property + def can_edit(self) -> bool: + """Indicates whether the requesting user has permission to edit the WriteUp""" + return self._can_edit + + @can_edit.setter + def can_edit(self, can_edit: bool): + if can_edit is None: + del self.can_edit + return + if not isinstance(can_edit, bool): + raise TypeError('can_edit must be of type bool') + self._can_edit = can_edit + + @property + def can_delete(self) -> bool: + """Indicates whether the requesting user has permission to delete the WriteUp""" + return self._can_delete + + @can_delete.setter + def can_delete(self, can_delete: bool): + if can_delete is None: + del self.can_delete + return + if not isinstance(can_delete, bool): + raise TypeError('can_delete must be of type bool') + self._can_delete = can_delete + + @property + def content_state(self) -> 'ContentState': + """Represents the content state of the WriteUp""" + return self._content_state + + @content_state.setter + def content_state(self, content_state: 'ContentState'): + if content_state is None: + del self.content_state + return + if not isinstance(content_state, ContentState): + raise TypeError('content_state must be of type ContentState') + self._content_state = content_state + + @property + def is_spammed(self) -> bool: + """Indicates whether the WriteUp has been marked as spam by moderation""" + return self._is_spammed + + @is_spammed.setter + def is_spammed(self, is_spammed: bool): + if is_spammed is None: + del self.is_spammed + return + if not isinstance(is_spammed, bool): + raise TypeError('is_spammed must be of type bool') + self._is_spammed = is_spammed + + @property + def license(self) -> Optional['License']: + """The license that applies to the WriteUp""" + return self._license or None + + @license.setter + def license(self, license: Optional[Optional['License']]): + if license is None: + del self.license + return + if not isinstance(license, License): + raise TypeError('license must be of type License') + self._license = license + + @property + def authors(self) -> str: + """Comma-separated list of the authors of the WriteUp""" + return self._authors or "" + + @authors.setter + def authors(self, authors: Optional[str]): + if authors is None: + del self.authors + return + if not isinstance(authors, str): + raise TypeError('authors must be of type str') + self._authors = authors + + @property + def thumbnail_image_url(self) -> str: + """Url of thumbnail image to represent the WriteUp""" + return self._thumbnail_image_url + + @thumbnail_image_url.setter + def thumbnail_image_url(self, thumbnail_image_url: str): + if thumbnail_image_url is None: + del self.thumbnail_image_url + return + if not isinstance(thumbnail_image_url, str): + raise TypeError('thumbnail_image_url must be of type str') + self._thumbnail_image_url = thumbnail_image_url + + @property + def original_image_url(self) -> str: + """Url of original image that's used by the cover and thumbnail image""" + return self._original_image_url + + @original_image_url.setter + def original_image_url(self, original_image_url: str): + if original_image_url is None: + del self.original_image_url + return + if not isinstance(original_image_url, str): + raise TypeError('original_image_url must be of type str') + self._original_image_url = original_image_url + + @property + def image_info(self) -> Optional['WriteUpImageInfo']: + """Crop settings for cover and thumbnail images""" + return self._image_info + + @image_info.setter + def image_info(self, image_info: Optional['WriteUpImageInfo']): + if image_info is None: + del self.image_info + return + if not isinstance(image_info, WriteUpImageInfo): + raise TypeError('image_info must be of type WriteUpImageInfo') + self._image_info = image_info + + @property + def can_pin(self) -> bool: + """Indicates whether the requesting user can pin the WriteUp to their profile""" + return self._can_pin + + @can_pin.setter + def can_pin(self, can_pin: bool): + if can_pin is None: + del self.can_pin + return + if not isinstance(can_pin, bool): + raise TypeError('can_pin must be of type bool') + self._can_pin = can_pin + + @property + def collaborators(self) -> Optional[List[Optional['UserAvatar']]]: + r""" + Collaborators on Competition or Hackathon WriteUp, i.e. team members in a + hackathon competition + """ + return self._collaborators + + @collaborators.setter + def collaborators(self, collaborators: Optional[List[Optional['UserAvatar']]]): + if collaborators is None: + del self.collaborators + return + if not isinstance(collaborators, list): + raise TypeError('collaborators must be of type list') + if not all([isinstance(t, UserAvatar) for t in collaborators]): + raise TypeError('collaborators must contain only items of type UserAvatar') + self._collaborators = collaborators + + @property + def publish_time(self) -> datetime: + """Time when WriteUp was last published""" + return self._publish_time + + @publish_time.setter + def publish_time(self, publish_time: datetime): + if publish_time is None: + del self.publish_time + return + if not isinstance(publish_time, datetime): + raise TypeError('publish_time must be of type datetime') + self._publish_time = publish_time + + +class WriteUpImageInfo(KaggleObject): + r""" + Attributes: + card_image_left (int) + card_image_top (int) + card_image_height (int) + card_image_width (int) + cover_image_left (int) + cover_image_height (int) + cover_image_top (int) + cover_image_width (int) + """ + + def __init__(self): + self._card_image_left = 0 + self._card_image_top = 0 + self._card_image_height = 0 + self._card_image_width = 0 + self._cover_image_left = 0 + self._cover_image_height = 0 + self._cover_image_top = 0 + self._cover_image_width = 0 + self._freeze() + + @property + def card_image_left(self) -> int: + return self._card_image_left + + @card_image_left.setter + def card_image_left(self, card_image_left: int): + if card_image_left is None: + del self.card_image_left + return + if not isinstance(card_image_left, int): + raise TypeError('card_image_left must be of type int') + self._card_image_left = card_image_left + + @property + def card_image_top(self) -> int: + return self._card_image_top + + @card_image_top.setter + def card_image_top(self, card_image_top: int): + if card_image_top is None: + del self.card_image_top + return + if not isinstance(card_image_top, int): + raise TypeError('card_image_top must be of type int') + self._card_image_top = card_image_top + + @property + def card_image_height(self) -> int: + return self._card_image_height + + @card_image_height.setter + def card_image_height(self, card_image_height: int): + if card_image_height is None: + del self.card_image_height + return + if not isinstance(card_image_height, int): + raise TypeError('card_image_height must be of type int') + self._card_image_height = card_image_height + + @property + def card_image_width(self) -> int: + return self._card_image_width + + @card_image_width.setter + def card_image_width(self, card_image_width: int): + if card_image_width is None: + del self.card_image_width + return + if not isinstance(card_image_width, int): + raise TypeError('card_image_width must be of type int') + self._card_image_width = card_image_width + + @property + def cover_image_left(self) -> int: + return self._cover_image_left + + @cover_image_left.setter + def cover_image_left(self, cover_image_left: int): + if cover_image_left is None: + del self.cover_image_left + return + if not isinstance(cover_image_left, int): + raise TypeError('cover_image_left must be of type int') + self._cover_image_left = cover_image_left + + @property + def cover_image_height(self) -> int: + return self._cover_image_height + + @cover_image_height.setter + def cover_image_height(self, cover_image_height: int): + if cover_image_height is None: + del self.cover_image_height + return + if not isinstance(cover_image_height, int): + raise TypeError('cover_image_height must be of type int') + self._cover_image_height = cover_image_height + + @property + def cover_image_top(self) -> int: + return self._cover_image_top + + @cover_image_top.setter + def cover_image_top(self, cover_image_top: int): + if cover_image_top is None: + del self.cover_image_top + return + if not isinstance(cover_image_top, int): + raise TypeError('cover_image_top must be of type int') + self._cover_image_top = cover_image_top + + @property + def cover_image_width(self) -> int: + return self._cover_image_width + + @cover_image_width.setter + def cover_image_width(self, cover_image_width: int): + if cover_image_width is None: + del self.cover_image_width + return + if not isinstance(cover_image_width, int): + raise TypeError('cover_image_width must be of type int') + self._cover_image_width = cover_image_width + + +class WriteUpLink(KaggleObject): + r""" + Attributes: + id (int) + Id of the WriteUpLink + title (str) + Title of the link + sort_key (float) + Used to specify the sort ordering of links + location (WriteUpLinkLocation) + Determines where links should be displayed in the UI + url (str) + URL destination of the link + dataset_id (int) + kernel_id (int) + model_id (int) + description (str) + Provides more context about the current link + image (CroppedImageUpload) + Only eligible on requests. If set, the provided image blob will be + stored in GCS and a GCS URL associated with the link. 'url' should not be + set if this field is provided. + media_type (WriteUpLinkMediaType) + Indicates the media type of the link's url, as a best effort. This should + always be set when the link location is 'carousel'. + resource (WriteUpLinkResource) + Resource data to be presented in cards + external_thumbnail_image_url (str) + External image URL that points to either a thumbnail image or favicon + icon for a non-Kaggle link + original_image_url (str) + Image URL for the full size, uncropped image for a carousel image + TODO(b/407831686): Clean up this pattern - we shouldn't have a specific + field that only applies to some types of WriteUpLinks. + entity_type (KaggleResourceType) + Specifies if the entity is a dataset, model, or kernel + benchmark_id (int) + """ + + def __init__(self): + self._id = 0 + self._title = "" + self._sort_key = 0.0 + self._location = WriteUpLinkLocation.WRITE_UP_LINK_LOCATION_UNSPECIFIED + self._url = None + self._dataset_id = None + self._kernel_id = None + self._model_id = None + self._description = None + self._image = None + self._media_type = WriteUpLinkMediaType.WRITE_UP_LINK_MEDIA_TYPE_UNSPECIFIED + self._resource = None + self._external_thumbnail_image_url = None + self._original_image_url = None + self._entity_type = None + self._benchmark_id = None + self._freeze() + + @property + def id(self) -> int: + """Id of the WriteUpLink""" + 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 title(self) -> str: + """Title of the link""" + 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 sort_key(self) -> float: + """Used to specify the sort ordering of links""" + return self._sort_key + + @sort_key.setter + def sort_key(self, sort_key: float): + if sort_key is None: + del self.sort_key + return + if not isinstance(sort_key, float): + raise TypeError('sort_key must be of type float') + self._sort_key = sort_key + + @property + def location(self) -> 'WriteUpLinkLocation': + """Determines where links should be displayed in the UI""" + return self._location + + @location.setter + def location(self, location: 'WriteUpLinkLocation'): + if location is None: + del self.location + return + if not isinstance(location, WriteUpLinkLocation): + raise TypeError('location must be of type WriteUpLinkLocation') + self._location = location + + @property + def media_type(self) -> 'WriteUpLinkMediaType': + r""" + Indicates the media type of the link's url, as a best effort. This should + always be set when the link location is 'carousel'. + """ + return self._media_type + + @media_type.setter + def media_type(self, media_type: 'WriteUpLinkMediaType'): + if media_type is None: + del self.media_type + return + if not isinstance(media_type, WriteUpLinkMediaType): + raise TypeError('media_type must be of type WriteUpLinkMediaType') + self._media_type = media_type + + @property + def url(self) -> str: + """URL destination of the link""" + return self._url or "" + + @url.setter + def url(self, url: Optional[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 + + @property + def dataset_id(self) -> int: + return self._dataset_id or 0 + + @dataset_id.setter + def dataset_id(self, dataset_id: int): + if dataset_id is None: + del self.dataset_id + return + if not isinstance(dataset_id, int): + raise TypeError('dataset_id must be of type int') + del self.kernel_id + del self.model_id + del self.benchmark_id + self._dataset_id = dataset_id + + @property + def kernel_id(self) -> int: + return self._kernel_id or 0 + + @kernel_id.setter + def kernel_id(self, kernel_id: int): + if kernel_id is None: + del self.kernel_id + return + if not isinstance(kernel_id, int): + raise TypeError('kernel_id must be of type int') + del self.dataset_id + del self.model_id + del self.benchmark_id + self._kernel_id = kernel_id + + @property + def model_id(self) -> int: + return self._model_id or 0 + + @model_id.setter + def model_id(self, model_id: int): + if model_id is None: + del self.model_id + return + if not isinstance(model_id, int): + raise TypeError('model_id must be of type int') + del self.dataset_id + del self.kernel_id + del self.benchmark_id + self._model_id = model_id + + @property + def benchmark_id(self) -> int: + return self._benchmark_id or 0 + + @benchmark_id.setter + def benchmark_id(self, benchmark_id: int): + if benchmark_id is None: + del self.benchmark_id + return + if not isinstance(benchmark_id, int): + raise TypeError('benchmark_id must be of type int') + del self.dataset_id + del self.kernel_id + del self.model_id + self._benchmark_id = benchmark_id + + @property + def description(self) -> str: + """Provides more context about the current link""" + 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 image(self) -> Optional['CroppedImageUpload']: + r""" + Only eligible on requests. If set, the provided image blob will be + stored in GCS and a GCS URL associated with the link. 'url' should not be + set if this field is provided. + """ + return self._image + + @image.setter + def image(self, image: Optional['CroppedImageUpload']): + if image is None: + del self.image + return + if not isinstance(image, CroppedImageUpload): + raise TypeError('image must be of type CroppedImageUpload') + self._image = image + + @property + def resource(self) -> Optional['WriteUpLinkResource']: + """Resource data to be presented in cards""" + return self._resource + + @resource.setter + def resource(self, resource: Optional['WriteUpLinkResource']): + if resource is None: + del self.resource + return + if not isinstance(resource, WriteUpLinkResource): + raise TypeError('resource must be of type WriteUpLinkResource') + self._resource = resource + + @property + def external_thumbnail_image_url(self) -> str: + r""" + External image URL that points to either a thumbnail image or favicon + icon for a non-Kaggle link + """ + return self._external_thumbnail_image_url or "" + + @external_thumbnail_image_url.setter + def external_thumbnail_image_url(self, external_thumbnail_image_url: Optional[str]): + if external_thumbnail_image_url is None: + del self.external_thumbnail_image_url + return + if not isinstance(external_thumbnail_image_url, str): + raise TypeError('external_thumbnail_image_url must be of type str') + self._external_thumbnail_image_url = external_thumbnail_image_url + + @property + def original_image_url(self) -> str: + r""" + Image URL for the full size, uncropped image for a carousel image + TODO(b/407831686): Clean up this pattern - we shouldn't have a specific + field that only applies to some types of WriteUpLinks. + """ + return self._original_image_url or "" + + @original_image_url.setter + def original_image_url(self, original_image_url: Optional[str]): + if original_image_url is None: + del self.original_image_url + return + if not isinstance(original_image_url, str): + raise TypeError('original_image_url must be of type str') + self._original_image_url = original_image_url + + @property + def entity_type(self) -> 'KaggleResourceType': + """Specifies if the entity is a dataset, model, or kernel""" + return self._entity_type or KaggleResourceType.KAGGLE_RESOURCE_TYPE_UNSPECIFIED + + @entity_type.setter + def entity_type(self, entity_type: Optional['KaggleResourceType']): + if entity_type is None: + del self.entity_type + return + if not isinstance(entity_type, KaggleResourceType): + raise TypeError('entity_type must be of type KaggleResourceType') + self._entity_type = entity_type + + +class WriteUpLinkResource(KaggleObject): + r""" + Similar to shape and nature to kaggle.users.ProfilePin + LINT.IfChange + + Attributes: + date (datetime) + upvote_count (int) + medal (Medal) + owner_user (UserAvatar) + owner_organization (OrganizationCard) + collaborators (UserAvatar) + usability_rating (float) + thumbnail_image_url (str) + is_private (bool) + is_phone_verified (bool) + """ + + def __init__(self): + self._date = None + self._upvote_count = None + self._medal = None + self._owner_user = None + self._owner_organization = None + self._collaborators = [] + self._usability_rating = None + self._thumbnail_image_url = None + self._is_private = None + self._is_phone_verified = None + self._freeze() + + @property + def date(self) -> datetime: + return self._date + + @date.setter + def date(self, date: datetime): + if date is None: + del self.date + return + if not isinstance(date, datetime): + raise TypeError('date must be of type datetime') + self._date = date + + @property + def upvote_count(self) -> int: + return self._upvote_count or 0 + + @upvote_count.setter + def upvote_count(self, upvote_count: Optional[int]): + if upvote_count is None: + del self.upvote_count + return + if not isinstance(upvote_count, int): + raise TypeError('upvote_count must be of type int') + self._upvote_count = upvote_count + + @property + def medal(self) -> 'Medal': + return self._medal or Medal.MEDAL_UNSPECIFIED + + @medal.setter + def medal(self, medal: Optional['Medal']): + if medal is None: + del self.medal + return + if not isinstance(medal, Medal): + raise TypeError('medal must be of type Medal') + self._medal = medal + + @property + def owner_user(self) -> Optional['UserAvatar']: + return self._owner_user or None + + @owner_user.setter + def owner_user(self, owner_user: Optional['UserAvatar']): + if owner_user is None: + del self.owner_user + return + if not isinstance(owner_user, UserAvatar): + raise TypeError('owner_user must be of type UserAvatar') + del self.owner_organization + self._owner_user = owner_user + + @property + def owner_organization(self) -> Optional['OrganizationCard']: + return self._owner_organization or None + + @owner_organization.setter + def owner_organization(self, owner_organization: Optional['OrganizationCard']): + if owner_organization is None: + del self.owner_organization + return + if not isinstance(owner_organization, OrganizationCard): + raise TypeError('owner_organization must be of type OrganizationCard') + del self.owner_user + self._owner_organization = owner_organization + + @property + def collaborators(self) -> Optional[List[Optional['UserAvatar']]]: + return self._collaborators + + @collaborators.setter + def collaborators(self, collaborators: Optional[List[Optional['UserAvatar']]]): + if collaborators is None: + del self.collaborators + return + if not isinstance(collaborators, list): + raise TypeError('collaborators must be of type list') + if not all([isinstance(t, UserAvatar) for t in collaborators]): + raise TypeError('collaborators must contain only items of type UserAvatar') + self._collaborators = collaborators + + @property + def usability_rating(self) -> float: + return self._usability_rating or 0.0 + + @usability_rating.setter + def usability_rating(self, usability_rating: Optional[float]): + if usability_rating is None: + del self.usability_rating + return + if not isinstance(usability_rating, float): + raise TypeError('usability_rating must be of type float') + self._usability_rating = usability_rating + + @property + def thumbnail_image_url(self) -> str: + return self._thumbnail_image_url or "" + + @thumbnail_image_url.setter + def thumbnail_image_url(self, thumbnail_image_url: Optional[str]): + if thumbnail_image_url is None: + del self.thumbnail_image_url + return + if not isinstance(thumbnail_image_url, str): + raise TypeError('thumbnail_image_url must be of type str') + self._thumbnail_image_url = thumbnail_image_url + + @property + def is_private(self) -> bool: + return self._is_private or False + + @is_private.setter + def is_private(self, is_private: Optional[bool]): + if is_private is None: + del self.is_private + return + if not isinstance(is_private, bool): + raise TypeError('is_private must be of type bool') + self._is_private = is_private + + @property + def is_phone_verified(self) -> bool: + return self._is_phone_verified or False + + @is_phone_verified.setter + def is_phone_verified(self, is_phone_verified: Optional[bool]): + if is_phone_verified is None: + del self.is_phone_verified + return + if not isinstance(is_phone_verified, bool): + raise TypeError('is_phone_verified must be of type bool') + self._is_phone_verified = is_phone_verified + + +WriteUp._fields = [ + FieldMetadata("id", "id", "_id", int, 0, PredefinedSerializer()), + FieldMetadata("topicId", "topic_id", "_topic_id", int, 0, PredefinedSerializer()), + FieldMetadata("title", "title", "_title", str, "", PredefinedSerializer()), + FieldMetadata("subtitle", "subtitle", "_subtitle", str, "", PredefinedSerializer()), + FieldMetadata("message", "message", "_message", CommentForumMessage, None, KaggleObjectSerializer()), + FieldMetadata("type", "type", "_type", WriteUpType, WriteUpType.WRITE_UP_TYPE_UNSPECIFIED, EnumSerializer()), + FieldMetadata("coverImageUrl", "cover_image_url", "_cover_image_url", str, "", PredefinedSerializer()), + FieldMetadata("writeUpLinks", "write_up_links", "_write_up_links", WriteUpLink, [], ListSerializer(KaggleObjectSerializer())), + FieldMetadata("tags", "tags", "_tags", Tag, [], ListSerializer(KaggleObjectSerializer())), + FieldMetadata("slug", "slug", "_slug", str, "", PredefinedSerializer()), + FieldMetadata("url", "url", "_url", str, "", PredefinedSerializer()), + FieldMetadata("createTime", "create_time", "_create_time", datetime, None, DateTimeSerializer()), + FieldMetadata("updateTime", "update_time", "_update_time", datetime, None, DateTimeSerializer()), + FieldMetadata("canEdit", "can_edit", "_can_edit", bool, False, PredefinedSerializer()), + FieldMetadata("canDelete", "can_delete", "_can_delete", bool, False, PredefinedSerializer()), + FieldMetadata("contentState", "content_state", "_content_state", ContentState, ContentState.CONTENT_STATE_UNSPECIFIED, EnumSerializer()), + FieldMetadata("isSpammed", "is_spammed", "_is_spammed", bool, False, PredefinedSerializer()), + FieldMetadata("license", "license", "_license", License, None, KaggleObjectSerializer(), optional=True), + FieldMetadata("authors", "authors", "_authors", str, None, PredefinedSerializer(), optional=True), + FieldMetadata("thumbnailImageUrl", "thumbnail_image_url", "_thumbnail_image_url", str, "", PredefinedSerializer()), + FieldMetadata("originalImageUrl", "original_image_url", "_original_image_url", str, "", PredefinedSerializer()), + FieldMetadata("imageInfo", "image_info", "_image_info", WriteUpImageInfo, None, KaggleObjectSerializer()), + FieldMetadata("canPin", "can_pin", "_can_pin", bool, False, PredefinedSerializer()), + FieldMetadata("collaborators", "collaborators", "_collaborators", UserAvatar, [], ListSerializer(KaggleObjectSerializer())), + FieldMetadata("publishTime", "publish_time", "_publish_time", datetime, None, DateTimeSerializer()), +] + +WriteUpImageInfo._fields = [ + FieldMetadata("cardImageLeft", "card_image_left", "_card_image_left", int, 0, PredefinedSerializer()), + FieldMetadata("cardImageTop", "card_image_top", "_card_image_top", int, 0, PredefinedSerializer()), + FieldMetadata("cardImageHeight", "card_image_height", "_card_image_height", int, 0, PredefinedSerializer()), + FieldMetadata("cardImageWidth", "card_image_width", "_card_image_width", int, 0, PredefinedSerializer()), + FieldMetadata("coverImageLeft", "cover_image_left", "_cover_image_left", int, 0, PredefinedSerializer()), + FieldMetadata("coverImageHeight", "cover_image_height", "_cover_image_height", int, 0, PredefinedSerializer()), + FieldMetadata("coverImageTop", "cover_image_top", "_cover_image_top", int, 0, PredefinedSerializer()), + FieldMetadata("coverImageWidth", "cover_image_width", "_cover_image_width", int, 0, PredefinedSerializer()), +] + +WriteUpLink._fields = [ + FieldMetadata("id", "id", "_id", int, 0, PredefinedSerializer()), + FieldMetadata("title", "title", "_title", str, "", PredefinedSerializer()), + FieldMetadata("sortKey", "sort_key", "_sort_key", float, 0.0, PredefinedSerializer()), + FieldMetadata("location", "location", "_location", WriteUpLinkLocation, WriteUpLinkLocation.WRITE_UP_LINK_LOCATION_UNSPECIFIED, EnumSerializer()), + FieldMetadata("url", "url", "_url", str, None, PredefinedSerializer(), optional=True), + FieldMetadata("datasetId", "dataset_id", "_dataset_id", int, None, PredefinedSerializer(), optional=True), + FieldMetadata("kernelId", "kernel_id", "_kernel_id", int, None, PredefinedSerializer(), optional=True), + FieldMetadata("modelId", "model_id", "_model_id", int, None, PredefinedSerializer(), optional=True), + FieldMetadata("description", "description", "_description", str, None, PredefinedSerializer(), optional=True), + FieldMetadata("image", "image", "_image", CroppedImageUpload, None, KaggleObjectSerializer()), + FieldMetadata("mediaType", "media_type", "_media_type", WriteUpLinkMediaType, WriteUpLinkMediaType.WRITE_UP_LINK_MEDIA_TYPE_UNSPECIFIED, EnumSerializer()), + FieldMetadata("resource", "resource", "_resource", WriteUpLinkResource, None, KaggleObjectSerializer()), + FieldMetadata("externalThumbnailImageUrl", "external_thumbnail_image_url", "_external_thumbnail_image_url", str, None, PredefinedSerializer(), optional=True), + FieldMetadata("originalImageUrl", "original_image_url", "_original_image_url", str, None, PredefinedSerializer(), optional=True), + FieldMetadata("entityType", "entity_type", "_entity_type", KaggleResourceType, None, EnumSerializer(), optional=True), + FieldMetadata("benchmarkId", "benchmark_id", "_benchmark_id", int, None, PredefinedSerializer(), optional=True), +] + +WriteUpLinkResource._fields = [ + FieldMetadata("date", "date", "_date", datetime, None, DateTimeSerializer()), + FieldMetadata("upvoteCount", "upvote_count", "_upvote_count", int, None, PredefinedSerializer(), optional=True), + FieldMetadata("medal", "medal", "_medal", Medal, None, EnumSerializer(), optional=True), + FieldMetadata("ownerUser", "owner_user", "_owner_user", UserAvatar, None, KaggleObjectSerializer(), optional=True), + FieldMetadata("ownerOrganization", "owner_organization", "_owner_organization", OrganizationCard, None, KaggleObjectSerializer(), optional=True), + FieldMetadata("collaborators", "collaborators", "_collaborators", UserAvatar, [], ListSerializer(KaggleObjectSerializer())), + FieldMetadata("usabilityRating", "usability_rating", "_usability_rating", float, None, PredefinedSerializer(), optional=True), + FieldMetadata("thumbnailImageUrl", "thumbnail_image_url", "_thumbnail_image_url", str, None, PredefinedSerializer(), optional=True), + FieldMetadata("isPrivate", "is_private", "_is_private", bool, None, PredefinedSerializer(), optional=True), + FieldMetadata("isPhoneVerified", "is_phone_verified", "_is_phone_verified", bool, None, PredefinedSerializer(), optional=True), +] + diff --git a/kagglesdk/kaggle_client.py b/kagglesdk/kaggle_client.py index dfaf5a1..c0910dd 100644 --- a/kagglesdk/kaggle_client.py +++ b/kagglesdk/kaggle_client.py @@ -1,5 +1,7 @@ from kagglesdk.admin.services.inbox_file_service import InboxFileClient +from kagglesdk.agents.services.agent_exam_service import AgentExamClient from kagglesdk.benchmarks.services.benchmarks_api_service import BenchmarksApiClient +from kagglesdk.benchmarks.services.benchmark_tasks_api_service import BenchmarkTasksApiClient from kagglesdk.blobs.services.blob_api_service import BlobApiClient from kagglesdk.common.services.operations_service import OperationsClient from kagglesdk.competitions.services.competition_api_service import CompetitionApiClient @@ -22,9 +24,14 @@ class Admin(object): def __init__(self, http_client: KaggleHttpClient): self.inbox_file_client = InboxFileClient(http_client) + class Agents(object): + def __init__(self, http_client: KaggleHttpClient): + self.agent_exam_client = AgentExamClient(http_client) + class Benchmarks(object): def __init__(self, http_client: KaggleHttpClient): self.benchmarks_api_client = BenchmarksApiClient(http_client) + self.benchmark_tasks_api_client = BenchmarkTasksApiClient(http_client) class Blobs(object): def __init__(self, http_client: KaggleHttpClient): @@ -72,6 +79,7 @@ def __init__(self, http_client: KaggleHttpClient): def __init__(self, env: KaggleEnv = None, verbose: bool = False, username: str = None, password: str = None, api_token: str = None, user_agent: str = '', response_processor=None): self._http_client = http_client = KaggleHttpClient(env, verbose, username=username, password=password, api_token=api_token, user_agent=user_agent, response_processor=response_processor) self.admin = KaggleClient.Admin(http_client) + self.agents = KaggleClient.Agents(http_client) self.benchmarks = KaggleClient.Benchmarks(http_client) self.blobs = KaggleClient.Blobs(http_client) self.common = KaggleClient.Common(http_client) diff --git a/kagglesdk/models/types/model_types.py b/kagglesdk/models/types/model_types.py index d89c686..40d9167 100644 --- a/kagglesdk/models/types/model_types.py +++ b/kagglesdk/models/types/model_types.py @@ -872,6 +872,10 @@ class ModelInstanceVersion(KaggleObject): thumbnail_url (str) is_private (bool) sigstore_state (SigstoreState) + model_id (int) + owner_slug (str) + model_slug (str) + model_instance_id (int) """ def __init__(self): @@ -885,6 +889,10 @@ def __init__(self): self._thumbnail_url = "" self._is_private = False self._sigstore_state = SigstoreState.SIGSTORE_STATE_UNSPECIFIED + self._model_id = 0 + self._owner_slug = "" + self._model_slug = "" + self._model_instance_id = 0 self._freeze() @property @@ -1017,6 +1025,58 @@ def sigstore_state(self, sigstore_state: 'SigstoreState'): raise TypeError('sigstore_state must be of type SigstoreState') self._sigstore_state = sigstore_state + @property + def model_id(self) -> int: + return self._model_id + + @model_id.setter + def model_id(self, model_id: int): + if model_id is None: + del self.model_id + return + if not isinstance(model_id, int): + raise TypeError('model_id must be of type int') + self._model_id = model_id + + @property + def owner_slug(self) -> str: + return self._owner_slug + + @owner_slug.setter + def owner_slug(self, owner_slug: str): + if owner_slug is None: + del self.owner_slug + return + if not isinstance(owner_slug, str): + raise TypeError('owner_slug must be of type str') + self._owner_slug = owner_slug + + @property + def model_slug(self) -> str: + return self._model_slug + + @model_slug.setter + def model_slug(self, model_slug: str): + if model_slug is None: + del self.model_slug + return + if not isinstance(model_slug, str): + raise TypeError('model_slug must be of type str') + self._model_slug = model_slug + + @property + def model_instance_id(self) -> int: + return self._model_instance_id + + @model_instance_id.setter + def model_instance_id(self, model_instance_id: int): + if model_instance_id is None: + del self.model_instance_id + return + if not isinstance(model_instance_id, int): + raise TypeError('model_instance_id must be of type int') + self._model_instance_id = model_instance_id + class ModelInstanceVersionList(KaggleObject): r""" @@ -1313,6 +1373,10 @@ def allow_model_gating(self, allow_model_gating: Optional[bool]): FieldMetadata("thumbnailUrl", "thumbnail_url", "_thumbnail_url", str, "", PredefinedSerializer()), FieldMetadata("isPrivate", "is_private", "_is_private", bool, False, PredefinedSerializer()), FieldMetadata("sigstoreState", "sigstore_state", "_sigstore_state", SigstoreState, SigstoreState.SIGSTORE_STATE_UNSPECIFIED, EnumSerializer()), + FieldMetadata("modelId", "model_id", "_model_id", int, 0, PredefinedSerializer()), + FieldMetadata("ownerSlug", "owner_slug", "_owner_slug", str, "", PredefinedSerializer()), + FieldMetadata("modelSlug", "model_slug", "_model_slug", str, "", PredefinedSerializer()), + FieldMetadata("modelInstanceId", "model_instance_id", "_model_instance_id", int, 0, PredefinedSerializer()), ] ModelInstanceVersionList._fields = [ diff --git a/kagglesdk/security/types/iam_service.py b/kagglesdk/security/types/iam_service.py index 09a078b..2b2eb14 100644 --- a/kagglesdk/security/types/iam_service.py +++ b/kagglesdk/security/types/iam_service.py @@ -269,6 +269,10 @@ class Principal(KaggleObject): group (GroupPrincipal) organization (OrganizationPrincipal) name (str) + is_fixed (bool) + Whether this principal binding is fixed (system-managed) and cannot be + removed by regular users. Fixed bindings are created by system accounts + (e.g., when sharing hackathon resources with competition groups). """ def __init__(self): @@ -276,6 +280,7 @@ def __init__(self): self._group = None self._organization = None self._name = "" + self._is_fixed = False self._freeze() @property @@ -336,6 +341,24 @@ def name(self, name: str): raise TypeError('name must be of type str') self._name = name + @property + def is_fixed(self) -> bool: + r""" + Whether this principal binding is fixed (system-managed) and cannot be + removed by regular users. Fixed bindings are created by system accounts + (e.g., when sharing hackathon resources with competition groups). + """ + return self._is_fixed + + @is_fixed.setter + def is_fixed(self, is_fixed: bool): + if is_fixed is None: + del self.is_fixed + return + if not isinstance(is_fixed, bool): + raise TypeError('is_fixed must be of type bool') + self._is_fixed = is_fixed + class SetIamPolicyRequest(KaggleObject): r""" @@ -481,6 +504,7 @@ def avatar(self, avatar: Optional['UserAvatar']): FieldMetadata("group", "group", "_group", GroupPrincipal, None, KaggleObjectSerializer(), optional=True), FieldMetadata("organization", "organization", "_organization", OrganizationPrincipal, None, KaggleObjectSerializer(), optional=True), FieldMetadata("name", "name", "_name", str, "", PredefinedSerializer()), + FieldMetadata("isFixed", "is_fixed", "_is_fixed", bool, False, PredefinedSerializer()), ] SetIamPolicyRequest._fields = [ diff --git a/kagglesdk/security/types/security_types.py b/kagglesdk/security/types/security_types.py index eb44f42..a1574dd 100644 --- a/kagglesdk/security/types/security_types.py +++ b/kagglesdk/security/types/security_types.py @@ -37,6 +37,7 @@ class KaggleResourceType(enum.Enum): KAGGLE_RESOURCE_TYPE_OAUTH_CLIENTS = 138 KAGGLE_RESOURCE_TYPE_RESOURCE_ACCESS_GROUPS = 140 KAGGLE_RESOURCE_TYPE_OPERATIONS = 142 + KAGGLE_RESOURCE_TYPE_AGENT_EXAMS = 144 KAGGLE_RESOURCE_TYPE_FORUMS = 200 """---------- Community ----------""" KAGGLE_RESOURCE_TYPE_FORUM_TOPICS = 202 diff --git a/kagglesdk/tags/__init__.py b/kagglesdk/tags/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/kagglesdk/tags/types/__init__.py b/kagglesdk/tags/types/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/kagglesdk/tags/types/tag_service.py b/kagglesdk/tags/types/tag_service.py new file mode 100644 index 0000000..fac484b --- /dev/null +++ b/kagglesdk/tags/types/tag_service.py @@ -0,0 +1,235 @@ +from kagglesdk.kaggle_object import * +from typing import Optional + +class Tag(KaggleObject): + r""" + Attributes: + id (int) + The unique identifier for a tag + name (str) + The name of a tag + full_path (str) + The complete path for a tag, showing its ancestors, separated by > + listing_url (str) + The URL to link to an appropriate listing for the tag, e.g. datasets + listing filtered by tag + description (str) + The description for a given tag + dataset_count (int) + The count of datasets tagged with a given tag + competition_count (int) + The count of competitions tagged with a given tag + notebook_count (int) + The count of notebooks tagged with a given tag + tag_url (str) + The URL to link directly to a given tag + display_name (str) + The display name for a given tag + google_material_icon (str) + Google Material Icon (previously FontAwesomeIcon) + model_count (int) + The count of models tagged with a given tag + """ + + def __init__(self): + self._id = 0 + self._name = "" + self._full_path = "" + self._listing_url = "" + self._description = None + self._dataset_count = 0 + self._competition_count = 0 + self._notebook_count = 0 + self._tag_url = "" + self._display_name = "" + self._google_material_icon = "" + self._model_count = 0 + self._freeze() + + @property + def id(self) -> int: + """The unique identifier for a tag""" + 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 name(self) -> str: + """The name of a tag""" + 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 full_path(self) -> str: + """The complete path for a tag, showing its ancestors, separated by >""" + return self._full_path + + @full_path.setter + def full_path(self, full_path: str): + if full_path is None: + del self.full_path + return + if not isinstance(full_path, str): + raise TypeError('full_path must be of type str') + self._full_path = full_path + + @property + def listing_url(self) -> str: + r""" + The URL to link to an appropriate listing for the tag, e.g. datasets + listing filtered by tag + """ + return self._listing_url + + @listing_url.setter + def listing_url(self, listing_url: str): + if listing_url is None: + del self.listing_url + return + if not isinstance(listing_url, str): + raise TypeError('listing_url must be of type str') + self._listing_url = listing_url + + @property + def description(self) -> str: + """The description for a given tag""" + 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 dataset_count(self) -> int: + """The count of datasets tagged with a given tag""" + return self._dataset_count + + @dataset_count.setter + def dataset_count(self, dataset_count: int): + if dataset_count is None: + del self.dataset_count + return + if not isinstance(dataset_count, int): + raise TypeError('dataset_count must be of type int') + self._dataset_count = dataset_count + + @property + def competition_count(self) -> int: + """The count of competitions tagged with a given tag""" + return self._competition_count + + @competition_count.setter + def competition_count(self, competition_count: int): + if competition_count is None: + del self.competition_count + return + if not isinstance(competition_count, int): + raise TypeError('competition_count must be of type int') + self._competition_count = competition_count + + @property + def notebook_count(self) -> int: + """The count of notebooks tagged with a given tag""" + return self._notebook_count + + @notebook_count.setter + def notebook_count(self, notebook_count: int): + if notebook_count is None: + del self.notebook_count + return + if not isinstance(notebook_count, int): + raise TypeError('notebook_count must be of type int') + self._notebook_count = notebook_count + + @property + def model_count(self) -> int: + """The count of models tagged with a given tag""" + return self._model_count + + @model_count.setter + def model_count(self, model_count: int): + if model_count is None: + del self.model_count + return + if not isinstance(model_count, int): + raise TypeError('model_count must be of type int') + self._model_count = model_count + + @property + def tag_url(self) -> str: + """The URL to link directly to a given tag""" + return self._tag_url + + @tag_url.setter + def tag_url(self, tag_url: str): + if tag_url is None: + del self.tag_url + return + if not isinstance(tag_url, str): + raise TypeError('tag_url must be of type str') + self._tag_url = tag_url + + @property + def display_name(self) -> str: + """The display name for a given tag""" + return self._display_name + + @display_name.setter + def display_name(self, display_name: 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 google_material_icon(self) -> str: + """Google Material Icon (previously FontAwesomeIcon)""" + return self._google_material_icon + + @google_material_icon.setter + def google_material_icon(self, google_material_icon: str): + if google_material_icon is None: + del self.google_material_icon + return + if not isinstance(google_material_icon, str): + raise TypeError('google_material_icon must be of type str') + self._google_material_icon = google_material_icon + + +Tag._fields = [ + FieldMetadata("id", "id", "_id", int, 0, PredefinedSerializer()), + FieldMetadata("name", "name", "_name", str, "", PredefinedSerializer()), + FieldMetadata("fullPath", "full_path", "_full_path", str, "", PredefinedSerializer()), + FieldMetadata("listingUrl", "listing_url", "_listing_url", str, "", PredefinedSerializer()), + FieldMetadata("description", "description", "_description", str, None, PredefinedSerializer(), optional=True), + FieldMetadata("datasetCount", "dataset_count", "_dataset_count", int, 0, PredefinedSerializer()), + FieldMetadata("competitionCount", "competition_count", "_competition_count", int, 0, PredefinedSerializer()), + FieldMetadata("notebookCount", "notebook_count", "_notebook_count", int, 0, PredefinedSerializer()), + FieldMetadata("tagUrl", "tag_url", "_tag_url", str, "", PredefinedSerializer()), + FieldMetadata("displayName", "display_name", "_display_name", str, "", PredefinedSerializer()), + FieldMetadata("googleMaterialIcon", "google_material_icon", "_google_material_icon", str, "", PredefinedSerializer()), + FieldMetadata("modelCount", "model_count", "_model_count", int, 0, PredefinedSerializer()), +] + diff --git a/kagglesdk/users/types/legacy_organizations_service.py b/kagglesdk/users/types/legacy_organizations_service.py new file mode 100644 index 0000000..68208d3 --- /dev/null +++ b/kagglesdk/users/types/legacy_organizations_service.py @@ -0,0 +1,78 @@ +from kagglesdk.kaggle_object import * + +class OrganizationCard(KaggleObject): + r""" + Attributes: + name (str) + id (int) + thumbnail_image_url (str) + slug (str) + """ + + def __init__(self): + self._name = "" + self._id = 0 + self._thumbnail_image_url = "" + self._slug = "" + 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 id(self) -> int: + 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 thumbnail_image_url(self) -> str: + return self._thumbnail_image_url + + @thumbnail_image_url.setter + def thumbnail_image_url(self, thumbnail_image_url: str): + if thumbnail_image_url is None: + del self.thumbnail_image_url + return + if not isinstance(thumbnail_image_url, str): + raise TypeError('thumbnail_image_url must be of type str') + self._thumbnail_image_url = thumbnail_image_url + + @property + def slug(self) -> str: + return self._slug + + @slug.setter + def slug(self, slug: str): + if slug is None: + del self.slug + return + if not isinstance(slug, str): + raise TypeError('slug must be of type str') + self._slug = slug + + +OrganizationCard._fields = [ + FieldMetadata("name", "name", "_name", str, "", PredefinedSerializer()), + FieldMetadata("id", "id", "_id", int, 0, PredefinedSerializer()), + FieldMetadata("thumbnailImageUrl", "thumbnail_image_url", "_thumbnail_image_url", str, "", PredefinedSerializer()), + FieldMetadata("slug", "slug", "_slug", str, "", PredefinedSerializer()), +] + diff --git a/kagglesdk/users/types/progression_service.py b/kagglesdk/users/types/progression_service.py index 4b916bd..965058d 100644 --- a/kagglesdk/users/types/progression_service.py +++ b/kagglesdk/users/types/progression_service.py @@ -1,5 +1,11 @@ import enum +class Medal(enum.Enum): + MEDAL_UNSPECIFIED = 0 + GOLD = 1 + SILVER = 2 + BRONZE = 3 + class UserAchievementType(enum.Enum): USER_ACHIEVEMENT_TYPE_UNSPECIFIED = 0 USER_ACHIEVEMENT_TYPE_COMPETITIONS = 1