From 57997b99210a14b62397121b8060be2b1673c1bd Mon Sep 17 00:00:00 2001 From: "changjun.zhu" Date: Tue, 23 Nov 2021 17:26:22 +0800 Subject: [PATCH] feat(client): design structure and interfaces of squashAndMergeJob --- tensorbay/client/dataset.py | 4 +- tensorbay/client/job.py | 78 ++++++++++++++++++++++++++++ tensorbay/client/version.py | 101 ++++++++++++++++++++++++++++++++++++ 3 files changed, 181 insertions(+), 2 deletions(-) create mode 100644 tensorbay/client/job.py diff --git a/tensorbay/client/dataset.py b/tensorbay/client/dataset.py index 3451b030e..a8d4639b9 100644 --- a/tensorbay/client/dataset.py +++ b/tensorbay/client/dataset.py @@ -41,7 +41,7 @@ from tensorbay.client.segment import _STRATEGIES, FusionSegmentClient, SegmentClient from tensorbay.client.statistics import Statistics from tensorbay.client.status import Status -from tensorbay.client.version import VersionControlMixin +from tensorbay.client.version import VersionControlMixin, JobMixin from tensorbay.dataset import AuthData, Data, Frame, FusionSegment, Notes, RemoteData, Segment from tensorbay.exception import ( FrameError, @@ -58,7 +58,7 @@ logger = logging.getLogger(__name__) -class DatasetClientBase(VersionControlMixin): +class DatasetClientBase(VersionControlMixin, JobMixin): """This class defines the basic concept of the dataset client. A :class:`DatasetClientBase` contains the information needed for diff --git a/tensorbay/client/job.py b/tensorbay/client/job.py new file mode 100644 index 000000000..184b2257f --- /dev/null +++ b/tensorbay/client/job.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python3 +# +# Copyright 2021 Graviti. Licensed under MIT License. +# + +"""Basic structures of asynchronous jobs.""" + +from typing import Any, Dict, Optional + + +class Job: # pylint: disable=too-many-instance-attributes + """This class defines :class:`Job`. + + Arguments: + title: Title of the Job. + job_id: ID of the Job. + job_type: Type of the Job. + creator: The creator of the Job. + arguments: Arguments of the Job. + created_at: The time when the Job is created. + started_at: The time when the Job is started. + limit_retry: The limit retry times of the Job. + finished_at: The time when the Job is finished. + description: The description of the Job. + + """ + + def __init__( # pylint: disable=too-many-arguments + self, + title: str, + job_id: str, + job_type: str, + creator: str, + arguments: Dict[str, Any], + created_at: str, + started_at: str, + limit_retry: int, + finished_at: Optional[str] = None, + description: Optional[str] = "", + ) -> None: + self.title = title + self.job_id = job_id + self.job_type = job_type + self.creator = creator + self.arguments = arguments + self.created_at = created_at + self.started_at = started_at + self.limit_retry = limit_retry + self.finished_at = finished_at + self.description = description + + def get_status(self) -> Dict[str, Any]: + """Get the status of the Job. + + Return: + The status dict of the Job. + + """ + + def get_log(self) -> str: + """Get the log of the Job. + + Return: + The log of the Job. + + """ + + +class SquashAndMergeJob(Job): + """This class defines :class:`SquashAndMergeJob`.""" + + def get_result(self) -> Dict[str, int]: + """Get the result of the SquashAndMergeJob. + + Return: + The result dict of the SquashAndMergeJob. + + """ diff --git a/tensorbay/client/version.py b/tensorbay/client/version.py index cf8a427fe..88cb71bf7 100644 --- a/tensorbay/client/version.py +++ b/tensorbay/client/version.py @@ -7,6 +7,7 @@ from typing import Any, Dict, Generator, Optional, Union +from tensorbay.client.job import SquashAndMergeJob from tensorbay.client.lazy import PagingList from tensorbay.client.requests import Client from tensorbay.client.status import Status @@ -582,3 +583,103 @@ def delete_tag(self, name: str) -> None: delete_data: Dict[str, Any] = {"name": name} self._client.open_api_do("DELETE", "tags", self._dataset_id, json=delete_data) + + +class JobMixin: # pylint: disable=too-many-public-methods + """A mixin class supporting asynchronous jobs. + + Arguments: + _dataset_id: Dataset ID. + _client: The client to interact between local and TensorBay. + _status: The version control status of the dataset. + + """ + + _dataset_id: str + _client: Client + _status: Status + + def _create_job( # pylint: disable=too-many-arguments + self, + title: str, + job_type: str, + arguments: Dict[str, Any], + description: str = "", + limit_retry: int = 3, + ) -> str: + """Create a :class:`Job`. + + Arguments: + title: The SquashAndMergeJob title. + job_type: The type of Job. + arguments: The arguments dict of the specific job. + description: The SquashAndMergeJob description. + limit_retry: The limit retry times of the SquashAndMergeJob. + + Returns:# flake8: noqa: DAR202 + The id of the job. + + """ + + def _get_job(self, job_id: str) -> Dict[str, Any]: + """Get a :class:`Job`. + + Arguments: + job_id: The Job id. + + Returns:# flake8: noqa: DAR202 + The info of Job. + + """ + + def create_squash_and_merge_job( + self, + title: str, + description: str = "", + limit_retry: int = 3, + *, + draft_title: str, + source_branch_name: str, + target_branch_name: Optional[str] = None, + draft_description: str = "", + strategy: Optional[str] = "abort", + ) -> SquashAndMergeJob: + """Create a :class:`SquashAndMergeJob`. + + Squash commits in source branch, then merge into target branch by creating a new draft. + If the target branch name is not given, the draft will be based on the branch name stored + in the dataset client. And during merging, the conflicts between branches can be resolved + in three different strategies: "abort", "override" and "skip". + + Arguments: + title: The SquashAndMergeJob title. + description: The SquashAndMergeJob description. + limit_retry: The limit retry times of the SquashAndMergeJob. + draft_title: The draft title. + source_branch_name: The name of the branch to be squashed. + target_branch_name: The target branch name of the merge operation. + draft_description: The draft description. + strategy: The strategy of handling the branch conflict. There are three options: + + 1. "abort": abort the opetation; + 2. "override": the squashed branch will override the target branch; + 3. "skip": keep the origin branch. + + Raises:# flake8: noqa: F402 + StatusError: When squashing and merging without basing on a branch. + + Returns:# flake8: noqa: DAR202 + The SquashAndMergeJob. + + """ + + def get_squash_and_merge_job(self, job_id: str) -> SquashAndMergeJob: + """Get a :class:`SquashAndMergeJob`. + + Arguments: + job_id: The SquashAndMergeJob id. + + Returns:# flake8: noqa: DAR202 + The SquashAndMergeJob. + + """