Skip to content

Commit df9bf59

Browse files
authored
Merge pull request #50 from kurusugawa-computer/fix/statistics-api
過去のアノテーション仕様を参照、統計APIの修正
2 parents 4f2e5f6 + dfc742a commit df9bf59

File tree

8 files changed

+104
-38
lines changed

8 files changed

+104
-38
lines changed

Pipfile

+1-2
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,7 @@ twine = "*"
2222
# Match sphinx version at ReadTheDocs
2323
sphinx = "==1.8.5"
2424
autoflake = "*"
25-
# Specify version temporarily
26-
docutils = "<=0.15.0"
25+
docutils = "*"
2726

2827
[pipenv]
2928
allow_prereleases = true

Pipfile.lock

+14-13
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

annofabapi/api.py

+21
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import functools
22
import json
33
import logging
4+
import warnings
45
from typing import Any, Callable, Dict, List, Optional, Tuple, Union # pylint: disable=unused-import
56

67
import backoff
@@ -177,6 +178,26 @@ def _request_wrapper(self, http_method: str, url_path: str, query_params: Option
177178
content = self._response_to_content(response)
178179
return content, response
179180

181+
def _get_signed_cookie(self, project_id):
182+
"""
183+
アノテーション仕様の履歴情報を取得するために、非公開APIにアクセスする。
184+
変更される可能性あり.
185+
186+
.. deprecated:: X
187+
188+
Args:
189+
project_id: プロジェクトID
190+
191+
Returns:
192+
Tuple[Content, Reponse)
193+
194+
"""
195+
warnings.warn("deprecated", DeprecationWarning)
196+
url_path = f'/private/projects/{project_id}/sign-headers'
197+
http_method = 'GET'
198+
keyword_params: Dict[str, Any] = {}
199+
return self._request_wrapper(http_method, url_path, **keyword_params)
200+
180201
#########################################
181202
# Public Method : Login
182203
#########################################

annofabapi/wrapper.py

+37
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import urllib.parse
66
from typing import Any, Callable, Dict, List, Optional, Tuple # pylint: disable=unused-import
77

8+
import requests
9+
810
import annofabapi.utils
911
from annofabapi import AnnofabApi
1012
from annofabapi.exceptions import AnnofabApiException
@@ -152,6 +154,22 @@ def get_all_annotation_list(self, project_id: str,
152154
#########################################
153155
# Public Method : AfAnnotationSpecsApi
154156
#########################################
157+
def get_annotation_specs_from_url(self, project_id: str, url: str) -> AnnotationSpecs:
158+
"""
159+
アノテーション仕様の履歴から取得したURLから、アノテーション仕様を取得する
160+
161+
Args:
162+
project_id: プロジェクトID
163+
url: アノテーション仕様の履歴から取得したURL
164+
165+
Returns:
166+
put_annotation_specsのContent
167+
"""
168+
cookies, _ = self.api._get_signed_cookie(project_id)
169+
kwargs = self.api._create_kwargs()
170+
kwargs.update({"cookies": cookies})
171+
return requests.get(url, **kwargs).json()
172+
155173
def copy_annotation_specs(self, src_project_id: str, dest_project_id: str,
156174
comment: Optional[str] = None) -> AnnotationSpecs:
157175
"""
@@ -262,6 +280,25 @@ def put_input_data_from_file(self, project_id: str, input_data_id: str, file_pat
262280

263281
return self.api.put_input_data(project_id, input_data_id, request_body=copied_request_body)[0]
264282

283+
#########################################
284+
# Public Method : AfStatisticsApi
285+
#########################################
286+
def get_worktime_statistics(self, project_id: str) -> Dict[str, Any]:
287+
"""
288+
タスク作業時間集計取得.
289+
Location Headerに記載されたURLのレスポンスをJSON形式で返す。
290+
291+
Args:
292+
project_id: プロジェクトID
293+
294+
Returns:
295+
タスク作業時間集計
296+
297+
"""
298+
_, response = self.api.get_worktime_statistics(project_id)
299+
url = response.headers['Location']
300+
return requests.get(url).json()
301+
265302
#########################################
266303
# Public Method : AfSupplementaryApi
267304
#########################################

tests/test_api.py

+7-7
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,14 @@
88
"""
99
import configparser
1010
import datetime
11-
import logging
1211
import os
1312
import time
1413
import uuid
1514
from distutils.util import strtobool
1615

1716
import annofabapi
1817
import annofabapi.utils
19-
from tests.utils_for_test import WrapperForTest, create_csv_for_task
18+
from tests.utils_for_test import WrapperForTest, create_csv_for_task, set_logging_from_inifile
2019

2120
# プロジェクトトップに移動する
2221
os.chdir(os.path.dirname(os.path.abspath(__file__)) + "/../")
@@ -29,10 +28,7 @@
2928
test_dir = './tests/data'
3029
out_dir = './tests/out'
3130

32-
if should_print_log_message:
33-
logging_formatter = '%(levelname)s : %(asctime)s : %(name)s : %(funcName)s : %(message)s'
34-
logging.basicConfig(format=logging_formatter)
35-
logging.getLogger("annofabapi").setLevel(level=logging.DEBUG)
31+
set_logging_from_inifile(inifile)
3632

3733
service = annofabapi.build_from_netrc()
3834
api = service.api
@@ -133,6 +129,10 @@ def test_annotation_specs():
133129
annotation_specs_histories = api.get_annotation_specs_histories(project_id)[0]
134130
assert type(annotation_specs_histories) == list
135131

132+
old_annotation_specs_url = annotation_specs_histories[0]["url"]
133+
old_annotation_specs = wrapper.get_annotation_specs_from_url(project_id, old_annotation_specs_url)
134+
assert type(old_annotation_specs) == dict
135+
136136

137137
def test_login():
138138
print(f"login")
@@ -314,7 +314,7 @@ def test_statistics():
314314
assert type(api.get_label_statistics(project_id)[0]) == list
315315

316316
print("get_worktime_statistics")
317-
assert type(api.get_worktime_statistics(project_id)[0]) == list
317+
assert type(wrapper.get_worktime_statistics(project_id)) == list
318318

319319

320320
def test_task():

tests/test_api2.py

+2-7
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,24 @@
33
44
"""
55
import configparser
6-
import logging
76
import os
87
from distutils.util import strtobool
98

109
import annofabapi
1110
import annofabapi.utils
12-
from tests.utils_for_test import WrapperForTest
11+
from tests.utils_for_test import WrapperForTest, set_logging_from_inifile
1312

1413
# プロジェクトトップに移動する
1514
os.chdir(os.path.dirname(os.path.abspath(__file__)) + "/../")
1615
inifile = configparser.ConfigParser()
1716
inifile.read('./pytest.ini', 'UTF-8')
1817
project_id = inifile.get('annofab', 'project_id')
1918
should_execute_job_api: bool = strtobool(inifile.get('annofab', 'should_execute_job_api'))
20-
should_print_log_message: bool = strtobool(inifile.get('annofab', 'should_print_log_message'))
2119

2220
test_dir = './tests/data'
2321
out_dir = './tests/out'
2422

25-
if should_print_log_message:
26-
logging_formatter = '%(levelname)s : %(asctime)s : %(name)s : %(funcName)s : %(message)s'
27-
logging.basicConfig(format=logging_formatter)
28-
logging.getLogger("annofabapi").setLevel(level=logging.DEBUG)
23+
set_logging_from_inifile(inifile)
2924

3025
service = annofabapi.build_from_netrc()
3126
test_wrapper = WrapperForTest(service.api)

tests/test_dataclass.py

+4-9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import configparser
2-
import logging
32
import os
43
from distutils.util import strtobool
54
from pathlib import Path
@@ -20,7 +19,7 @@
2019
from annofabapi.dataclass.supplementary import SupplementaryData
2120
from annofabapi.dataclass.task import Task, TaskHistory
2221
from annofabapi.dataclass.webhook import Webhook
23-
from tests.utils_for_test import WrapperForTest
22+
from tests.utils_for_test import WrapperForTest, set_logging_from_inifile
2423

2524
# プロジェクトトップに移動する
2625
os.chdir(os.path.dirname(os.path.abspath(__file__)) + "/../")
@@ -30,14 +29,10 @@
3029
task_id = inifile.get('annofab', 'task_id')
3130
input_data_id = inifile.get('annofab', 'input_data_id')
3231
should_execute_job_api: bool = strtobool(inifile.get('annofab', 'should_execute_job_api'))
33-
should_print_log_message: bool = strtobool(inifile.get('annofab', 'should_print_log_message'))
3432

35-
test_dir = Path('./tests/data')
33+
set_logging_from_inifile(inifile)
3634

37-
if should_print_log_message:
38-
logging_formatter = '%(levelname)s : %(asctime)s : %(name)s : %(funcName)s : %(message)s'
39-
logging.basicConfig(format=logging_formatter)
40-
logging.getLogger("annofabapi").setLevel(level=logging.DEBUG)
35+
test_dir = Path('./tests/data')
4136

4237
service = annofabapi.build_from_netrc()
4338
test_wrapper = WrapperForTest(service.api)
@@ -141,7 +136,7 @@ def test_statistics_get_label_statistics():
141136

142137

143138
def test_statistics_get_worktime_statistics():
144-
stat_list, _ = service.api.get_worktime_statistics(project_id)
139+
stat_list = service.wrapper.get_worktime_statistics(project_id)
145140
stat = WorktimeStatistics.from_dict(stat_list[0])
146141
assert type(stat) == WorktimeStatistics
147142

tests/utils_for_test.py

+18
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1+
import configparser
12
import csv
3+
import logging
24
import os
5+
from distutils.util import strtobool
36

47
from annofabapi import AnnofabApi
58

@@ -17,6 +20,21 @@ def create_csv_for_task(file_path, first_input_data):
1720
writer.writerows(lines)
1821

1922

23+
def set_logging_from_inifile(inifile: configparser.ConfigParser):
24+
"""
25+
読み込み済の inifile から、ロギングを設定する。
26+
27+
Args:
28+
inifile: 読み込み済の inifile
29+
30+
"""
31+
should_print_log_message: bool = strtobool(inifile.get('annofab', 'should_print_log_message'))
32+
if should_print_log_message:
33+
logging_formatter = '%(levelname)s : %(asctime)s : %(name)s : %(funcName)s : %(message)s'
34+
logging.basicConfig(format=logging_formatter)
35+
logging.getLogger("annofabapi").setLevel(level=logging.DEBUG)
36+
37+
2038
class WrapperForTest:
2139
"""
2240
テスト用のUtils

0 commit comments

Comments
 (0)