Skip to content

Commit 1aade08

Browse files
authored
[wrapper] operateTask APIの処理を分割したメソッドを作成 (#240)
* update * 作業ガイドを登録 * test project 作成 * [wrapper] operateTaskを分解したようなメソッドを追加 * [wrapper] operateTaskを分解したようなメソッドを追加 * format * format * version up * update README
1 parent 650320d commit 1aade08

File tree

6 files changed

+558
-65
lines changed

6 files changed

+558
-65
lines changed

README_for_developer.md

Lines changed: 60 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -2,60 +2,28 @@
22
開発者用のドキュメントです。
33
ソースコードの生成、テスト実行、リリース手順などを記載します。
44

5-
## Requirements
5+
# Requirements
66
* Bash
77
* Docker (OpenAPI Generatorを実行するのに必要)
88
* python 3.6+
9-
* poetry
109

11-
## Install
10+
# Install
1211
以下のコマンドを実行してください。開発に必要な環境が構築されます。
1312

1413
```bash
1514
$ make init
1615
```
1716

18-
## Source
17+
# Test
1918

20-
### ソースコードの生成
21-
annofabapiのいくつかのファイルは、[AnnoFab Web APIのOpenAPI Spec](https://annofab.com/docs/api/swagger.yaml)から自動生成しています。
22-
以下のコマンドを実行すると、ソースコードが生成されます。詳細は[generate/README.md](generate/README.md)を参照してください。
23-
24-
```
25-
# `generate/swagger/*.yaml`ファイルから、ソースコードを生成する
26-
$ generate/generate.sh
27-
28-
# AnnoFab WebAPIのOpenAPI Spec を`generate/swagger/`にダウンロードしてから、ソースコードを生成する
29-
$ generate/generate.sh --download
30-
31-
```
32-
33-
### フォーマットを実行
34-
以下のコマンドを実行してください。
35-
36-
```
37-
$ make format
38-
```
39-
40-
### lintを実行
41-
以下のコマンドを実行してください。
42-
43-
```
44-
$ make lint
45-
```
46-
47-
## Test
48-
49-
### テストの実行方法
19+
## テストの実行方法
5020
1. AnnoFabの認証情報を、`.netrc`ファイルまたは環境変数に設定する。
51-
2. `pytest.ini`に、テスト対象の`project_id``task_id`を指定する。
21+
2. 以下のコマンドを実行して、テスト用のプロジェクトとタスクを作成する。
22+
* `poetry run python tests/create_test_project.py --organization ${MY_ORGANIZATION}`
23+
3. `pytest.ini`に、テスト対象の`project_id``task_id`を指定する。
5224
* `task_id`はプロジェクト`project_id`配下であること
5325
* **【注意】テストを実行すると、AnnoFabプロジェクトの内容が変更される**
54-
3. `$ make test`コマンドを実行する。
55-
56-
#### タスクの前提条件
57-
* タスクの先頭画像にアノテーションが1個以上付与されている
58-
* タスクの先頭画像に検査コメントが1個以上付与されている
26+
4. `$ make test`コマンドを実行する。
5927

6028

6129
#### テストメソッドを指定してテストする方法
@@ -89,8 +57,17 @@ $ poetry run pytest --print_log_annofabapi tests
8957
* 「パスワード変更」など使用頻度が少なく、実行や確認がしづらいメソッド
9058

9159

60+
# Versioning
61+
annofabapiのバージョンはSemantic Versioning 2.0に従います。
62+
* メソッドが追加されたときは、マイナーバージョンを上げる。
63+
* annofabapiのバグ/ドキュメント修正などにより、annofabapiをリリースするときは、パッチバージョンを上げる。
64+
65+
annofabapiのバージョンは以下のファイルで定義しています。
66+
* `annofabapi/__version__.py`
67+
* `pyproject.toml`
9268

93-
## Release
69+
70+
# PyPIへのリリース方法
9471

9572
## 事前作業
9673

@@ -102,30 +79,12 @@ https://pypi.org/account/register/
10279
https://pypi.org/project/annofabapi/
10380

10481
## リリース方法
105-
106-
### 1. annofabapiのバージョンを上げる
107-
以下のファイルに記載されているバージョンを上げてください。
108-
* `annofabapi/__version__.py`
109-
* `pyproject.toml`
110-
111-
バージョンはSemantic Versioning 2.0に従います。
112-
* メソッドが追加されたときは、マイナーバージョンを上げる。
113-
* annofabapiのバグ/ドキュメント修正などにより、annofabapiをリリースするときは、パッチバージョンを上げる。
114-
115-
116-
### 2. PyPIに登録する
82+
以下のコマンドを実行してください。PyPIのユーザ名とパスワードの入力が求められます。
11783

11884
```
11985
$ make publish
12086
```
12187

122-
※ PyPIのユーザ名とパスワードの入力が求められます。
123-
124-
125-
126-
### 3. GitHubのリリースページに追加
127-
GitHubのRelease機能を使って、リリース情報を記載します。
128-
12988

13089
## Document
13190
### ドキュメントの作成
@@ -143,3 +102,44 @@ ReadTheDocsのビルド結果は https://readthedocs.org/projects/annofab-api-py
143102
## 開発フロー
144103
* masterブランチを元にしてブランチを作成して、プルリクを作成してください。masterブランチへの直接pushすることはGitHub上で禁止しています。
145104
* リリース時のソースはGitHubのRelease機能、またはPyPIからダウンロードしてください。
105+
106+
107+
108+
109+
-----------------
110+
# AnnoFab WebAPIの更新により、リリースする
111+
### 1.ソースコードの生成
112+
113+
annofabapiのいくつかのファイルは、[AnnoFab Web APIのOpenAPI Spec](https://annofab.com/docs/api/swagger.yaml)から自動生成しています。
114+
以下のコマンドを実行すると、ソースコードが生成されます。詳細は[generate/README.md](generate/README.md)を参照してください。
115+
116+
```
117+
# `generate/swagger/*.yaml`ファイルから、ソースコードを生成する
118+
$ generate/generate.sh
119+
120+
# AnnoFab WebAPIのOpenAPI Spec を`generate/swagger/`にダウンロードしてから、ソースコードを生成する
121+
$ generate/generate.sh --download
122+
123+
$ make format && make lint
124+
```
125+
126+
### 2.テストの実施
127+
「テストの実行方法」を参照
128+
129+
### 3.versionを上げる
130+
「Versioning」を参照
131+
132+
### 4.プルリクを作ってマージする
133+
134+
### 5.PyPIへパッケージをアップロードする
135+
「PyPIへのリリース方法」を参照
136+
137+
### 6.GitHubのリリースページに追加
138+
GitHubのRelease機能を使って、リリース情報を記載します。
139+
140+
141+
142+
143+
144+
145+

annofabapi/__version__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "0.40.1"
1+
__version__ = "0.40.2"

annofabapi/wrapper.py

Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
SimpleAnnotationDetail,
4040
SupplementaryData,
4141
Task,
42+
TaskStatus,
4243
)
4344
from annofabapi.parser import SimpleAnnotationDirParser, SimpleAnnotationParser
4445
from annofabapi.utils import _download, _log_error_response, _raise_for_status, allow_404_error, str_now
@@ -1448,6 +1449,222 @@ def get_all_tasks(self, project_id: str, query_params: Optional[Dict[str, Any]]
14481449
"""
14491450
return self._get_all_objects(self.api.get_tasks, limit=200, project_id=project_id, query_params=query_params)
14501451

1452+
def change_task_status_to_working(self, project_id: str, task_id: str) -> Task:
1453+
"""
1454+
タスクのステータスを「作業中」に変更します。
1455+
1456+
Notes:
1457+
* 現在タスクを担当しているユーザーのみ、この操作を行うことができます。
1458+
* 現在の状態が未着手(not_started)、休憩中(break)、保留(on_hold)のいずれかであるタスクに対してのみ、この操作を行うことができます。
1459+
1460+
Args:
1461+
project_id: プロジェクトID
1462+
task_id: タスクID
1463+
1464+
Returns:
1465+
変更後のタスク
1466+
"""
1467+
task, _ = self.api.get_task(project_id, task_id)
1468+
request_body = {
1469+
"status": TaskStatus.WORKING.value,
1470+
"account_id": self.api.account_id,
1471+
"last_updated_datetime": task["updated_datetime"],
1472+
}
1473+
updated_task, _ = self.api.operate_task(project_id, task_id, request_body=request_body)
1474+
return updated_task
1475+
1476+
def change_task_status_to_break(self, project_id: str, task_id: str) -> Task:
1477+
"""
1478+
タスクのステータスを「休憩中」に変更します。
1479+
1480+
Notes:
1481+
* 現在タスクを担当しているユーザーのみ、この操作を行うことができます。
1482+
* 現在の状態が作業中(working)のタスクに対してのみ、この操作を行うことができます。
1483+
1484+
Args:
1485+
project_id: プロジェクトID
1486+
task_id: タスクID
1487+
1488+
Returns:
1489+
変更後のタスク
1490+
"""
1491+
task, _ = self.api.get_task(project_id, task_id)
1492+
request_body = {
1493+
"status": TaskStatus.BREAK.value,
1494+
"account_id": self.api.account_id,
1495+
"last_updated_datetime": task["updated_datetime"],
1496+
}
1497+
updated_task, _ = self.api.operate_task(project_id, task_id, request_body=request_body)
1498+
return updated_task
1499+
1500+
def change_task_status_to_on_hold(self, project_id: str, task_id: str) -> Task:
1501+
"""
1502+
タスクのステータスを「保留」に変更します。
1503+
1504+
Notes:
1505+
* 現在タスクを担当しているユーザーのみ、この操作を行うことができます。
1506+
* 現在の状態が作業中(working)のタスクに対してのみ、この操作を行うことができます。
1507+
1508+
Args:
1509+
project_id: プロジェクトID
1510+
task_id: タスクID
1511+
1512+
Returns:
1513+
変更後のタスク
1514+
"""
1515+
task, _ = self.api.get_task(project_id, task_id)
1516+
request_body = {
1517+
"status": TaskStatus.ON_HOLD.value,
1518+
"account_id": self.api.account_id,
1519+
"last_updated_datetime": task["updated_datetime"],
1520+
}
1521+
updated_task, _ = self.api.operate_task(project_id, task_id, request_body=request_body)
1522+
return updated_task
1523+
1524+
def complete_task(self, project_id: str, task_id: str) -> Task:
1525+
"""
1526+
今のフェーズを完了させ、 次のフェーズに遷移させます。
1527+
教師付フェーズのときはタスクを提出します。
1528+
検査/受入フェーズのときは、タスクを合格にします。
1529+
1530+
1531+
Notes:
1532+
* 現在タスクを担当しているユーザーのみ、この操作を行うことができます。
1533+
* 現在の状態が作業中(working)のタスクに対してのみ、この操作を行うことができます。
1534+
1535+
Args:
1536+
project_id: プロジェクトID
1537+
task_id: タスクID
1538+
1539+
Returns:
1540+
変更後のタスク
1541+
"""
1542+
task, _ = self.api.get_task(project_id, task_id)
1543+
request_body = {
1544+
"status": TaskStatus.COMPLETE.value,
1545+
"account_id": self.api.account_id,
1546+
"last_updated_datetime": task["updated_datetime"],
1547+
}
1548+
updated_task, _ = self.api.operate_task(project_id, task_id, request_body=request_body)
1549+
return updated_task
1550+
1551+
def cancel_submitted_task(self, project_id: str, task_id: str) -> Task:
1552+
"""
1553+
タスクの提出を取り消します。
1554+
「提出されたタスク」とは以下の状態になっています。
1555+
* 教師付フェーズで「提出」ボタンを押して、検査/受入フェーズへ遷移したタスク
1556+
* 検査フェーズから「合格」ボタンを押して、受入フェーズへ遷移したタスク
1557+
1558+
Notes:
1559+
* 現在タスクを担当しているユーザーのみ、この操作を行うことができます。
1560+
* タスク提出後に検査/受入(抜取含む)等の作業が一切行われていない場合のみ、この操作を行うことができます。
1561+
* 現在の状態が未着手(not_started)のタスクに対してのみ、この操作を行うことができます。
1562+
* 現在のフェーズが検査(inspection)、もしくは受入(acceptance)のタスクに対してのみ、この操作を行うことができます。
1563+
1564+
Args:
1565+
project_id: プロジェクトID
1566+
task_id: タスクID
1567+
1568+
Returns:
1569+
変更後のタスク
1570+
"""
1571+
task, _ = self.api.get_task(project_id, task_id)
1572+
request_body = {
1573+
"status": TaskStatus.CANCELLED.value,
1574+
"account_id": self.api.account_id,
1575+
"last_updated_datetime": task["updated_datetime"],
1576+
}
1577+
updated_task, _ = self.api.operate_task(project_id, task_id, request_body=request_body)
1578+
return updated_task
1579+
1580+
def cancel_completed_task(self, project_id: str, task_id: str, operator_account_id: Optional[str] = None) -> Task:
1581+
"""
1582+
タスクの受入完了状態を取り消す。
1583+
1584+
Args:
1585+
project_id: プロジェクトID
1586+
task_id: タスクID
1587+
operator_account_id: 受入完了状態を取り消した後の担当者のaccount_id
1588+
1589+
Returns:
1590+
変更後のタスク
1591+
"""
1592+
1593+
task, _ = self.api.get_task(project_id, task_id)
1594+
1595+
request_body = {
1596+
"status": TaskStatus.NOT_STARTED.value,
1597+
"account_id": operator_account_id,
1598+
"last_updated_datetime": task["updated_datetime"],
1599+
}
1600+
updated_task, _ = self.api.operate_task(project_id, task_id, request_body=request_body)
1601+
return updated_task
1602+
1603+
def change_task_operator(
1604+
self, project_id: str, task_id: str, operator_account_id: Optional[str] = None
1605+
) -> Dict[str, Any]:
1606+
"""
1607+
タスクの担当者を変更します。
1608+
1609+
Notes:
1610+
* プロジェクトオーナー(owner)、もしくは受入担当者(accepter)のみ、この操作を行うことができます。
1611+
1612+
Args:
1613+
project_id: プロジェクトID
1614+
task_id: タスクID
1615+
operator_account_id: 新しい担当者のaccount_id。Noneの場合は、担当者を「未割り当て」にします。
1616+
1617+
Returns:
1618+
変更後のタスク
1619+
1620+
"""
1621+
task, _ = self.api.get_task(project_id, task_id)
1622+
1623+
request_body = {
1624+
"status": TaskStatus.NOT_STARTED.value,
1625+
"account_id": operator_account_id,
1626+
"last_updated_datetime": task["updated_datetime"],
1627+
}
1628+
updated_task, _ = self.api.operate_task(project_id, task_id, request_body=request_body)
1629+
return updated_task
1630+
1631+
def reject_task(self, project_id: str, task_id: str, force: bool = False) -> Dict[str, Any]:
1632+
"""
1633+
タスクを差し戻します。
1634+
* 通常の差し戻しの場合、タスクの担当者は未割り当てになります。
1635+
* 強制差し戻しの場合、タスクの担当者は直前の教師付フェーズの担当者になります。
1636+
1637+
Notes:
1638+
* 通常の差し戻しの場合
1639+
* 現在タスクを担当しているユーザーのみ、この操作を行うことができます。
1640+
* 現在の状態が作業中(working)のタスクに対してのみ、この操作を行うことができます。
1641+
* 現在のフェーズが検査(inspection)、もしくは受入(acceptance)のタスクに対してのみ、この操作を行うことができます。
1642+
* 強制差し戻しの場合
1643+
* タスクの状態・フェーズを無視して、フェーズを教師付け(annotation)に、状態を未作業(not started)に変更します。
1644+
* タスクの担当者としては、直前の教師付け(annotation)フェーズの担当者を割り当てます。
1645+
* この差戻しは、抜取検査・抜取受入のスキップ判定に影響を及ぼしません。
1646+
1647+
Args:
1648+
project_id: プロジェクトID
1649+
task_id: タスクID
1650+
force: Trueなら強制差し戻し、Falseなら通常の差し戻しを実施する
1651+
1652+
Returns:
1653+
変更後のタスク
1654+
1655+
"""
1656+
1657+
task, _ = self.api.get_task(project_id, task_id)
1658+
1659+
request_body = {
1660+
"status": TaskStatus.REJECTED.value,
1661+
"account_id": self.api.account_id,
1662+
"last_updated_datetime": task["updated_datetime"],
1663+
"force": force,
1664+
}
1665+
updated_task, _ = self.api.operate_task(project_id, task_id, request_body=request_body)
1666+
return updated_task
1667+
14511668
#########################################
14521669
# Public Method : Instruction
14531670
#########################################

0 commit comments

Comments
 (0)