Skip to content

Commit ca8152e

Browse files
authored
Merge pull request #90 from osmlab/dev
Merging Dev -> Master
2 parents 4258a98 + e783f38 commit ca8152e

File tree

8 files changed

+119
-3
lines changed

8 files changed

+119
-3
lines changed

CHANGELOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,21 @@ All notable changes to this project will be documented in this file. Dates are d
44

55
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
66

7+
#### [v1.7.0](https://github.com/osmlab/maproulette-python-client/compare/v1.6.0...v1.7.0)
8+
9+
> 7 September 2021
10+
11+
- Dev -> Master [`#88`](https://github.com/osmlab/maproulette-python-client/pull/88)
12+
- Updated changelog and version bump [`#87`](https://github.com/osmlab/maproulette-python-client/pull/87)
13+
- Encode slashes in challenge_name [`#82`](https://github.com/osmlab/maproulette-python-client/pull/82)
14+
- Add support for parameter "immediate" for delete_project(), closes #85 [`#86`](https://github.com/osmlab/maproulette-python-client/pull/86)
15+
- Changed response handling in case of JSON deserializing error [`#80`](https://github.com/osmlab/maproulette-python-client/pull/80)
16+
- Add endpoint to rebuild challenge [`#79`](https://github.com/osmlab/maproulette-python-client/pull/79)
17+
- add info where API KEY can be found [`#77`](https://github.com/osmlab/maproulette-python-client/pull/77)
18+
- Merge pull request #86 from rYR79435/deleteProjectImmediate [`#85`](https://github.com/osmlab/maproulette-python-client/issues/85)
19+
- Add support for parameter "immediate" for delete_project(), closes #85 [`#85`](https://github.com/osmlab/maproulette-python-client/issues/85)
20+
- Encode slashes in challenge_name, closes #81 [`#81`](https://github.com/osmlab/maproulette-python-client/issues/81)
21+
722
#### [v1.6.0](https://github.com/osmlab/maproulette-python-client/compare/v1.5.0...v1.6.0)
823

924
> 26 January 2021

maproulette/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,4 @@
1717
from .api.task import Task
1818
from .api.user import User
1919

20-
__version__ = '1.7.0'
20+
__version__ = '1.8.0'

maproulette/api/challenge.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,32 @@ def add_tasks_to_challenge(self, data, challenge_id):
278278
body=data)
279279
return response
280280

281+
def add_file_tasks_to_challenge(self, data, challenge_id, line_by_line="true", remove_unmatched="false",
282+
data_origin_date="", skip_snapshot="false"):
283+
"""Method to add tasks to an existing challenge with tasks as GeoJSON
284+
285+
:param data: a GeoJSON containing geometry of tasks to be added to a challenge
286+
:param challenge_id: the ID corresponding to the challenge that tasks will be added to
287+
:param line_by_line: whether or not the provided data is in line-by-line GeoJSON format
288+
:param remove_unmatched: whether or not the JSON provided includes seperate GeoJSON on each line
289+
:param data_origin_date: the date the data was sourced on
290+
:param skip_snapshot: whether or not to skip recording a snapshot before proceeding
291+
:returns: the API response from the PUT request
292+
"""
293+
query_params = {
294+
"lineByLine": str(line_by_line),
295+
"removeUnmatched": str(remove_unmatched),
296+
"dataOriginDate": str(data_origin_date),
297+
"skipSnapshot": str(skip_snapshot)
298+
}
299+
body = {'json': ('data', data)} # server only accepts dict with key 'json'
300+
301+
response = self.put_file(
302+
endpoint=f"/challenge/{challenge_id}/addFileTasks",
303+
body=body,
304+
params=query_params)
305+
return response
306+
281307
def delete_challenge(self, challenge_id, immediate="false"):
282308
"""Method to delete a challenge by using the corresponding challenge ID
283309

maproulette/api/maproulette_server.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,51 @@ def put(self, endpoint, body=None, params=None):
180180
"status": response.status_code
181181
}
182182

183+
def put_file(self, endpoint, body=None, params=None):
184+
"""Method that completes a multipart PUT request to the MapRoulette API
185+
186+
:param endpoint: the server endpoint to use for the PUT request
187+
:param body: the body of the request (optional)
188+
:param params: the parameters that pertain to the request (optional)
189+
:returns: a dictionary containing the API response status code as well as the decoded JSON response if decoding
190+
was successful. If not, the response text is returned.
191+
"""
192+
response = self.session.put(
193+
self.url + endpoint,
194+
params=params,
195+
files=body
196+
)
197+
try:
198+
response.raise_for_status()
199+
except requests.exceptions.HTTPError as e:
200+
if e.response.status_code == 400:
201+
raise InvalidJsonError(
202+
message=self.parse_response_message(e.response),
203+
status=e.response.status_code
204+
) from None
205+
elif e.response.status_code == 401:
206+
raise UnauthorizedError(
207+
message=self.parse_response_message(e.response),
208+
status=e.response.status_code
209+
) from None
210+
else:
211+
raise HttpError(
212+
message=self.parse_response_message(e.response),
213+
status=e.response.status_code
214+
) from None
215+
except (requests.ConnectionError, requests.Timeout) as e:
216+
raise ConnectionUnavailableError(e) from None
217+
try:
218+
return {
219+
"data": response.json(),
220+
"status": response.status_code
221+
}
222+
except ValueError:
223+
return {
224+
"data": response.text,
225+
"status": response.status_code
226+
}
227+
183228
def delete(self, endpoint, params=None):
184229
"""Method that completes a DELETE request to the MapRoulette API
185230

maproulette/api/task.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ def create_task(self, data):
3636
:param data: a JSON input containing task details
3737
:returns: the API response from the POST request
3838
"""
39+
if self.is_task_model(data):
40+
data = TaskModel.to_dict(data)
3941
response = self.post(
4042
endpoint="/task",
4143
body=data)

tests/test_challenge_api.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,22 @@ def test_add_tasks_to_challenge(self, mock_request, api_instance=api):
5757
json=test_geojson,
5858
params=None)
5959

60+
@patch('maproulette.api.maproulette_server.requests.Session.put')
61+
def test_add_file_tasks_to_challenge(self, mock_request, api_instance=api):
62+
test_challenge_id = '12978'
63+
data = {'json': ('data', test_geojson)}
64+
query_params = {
65+
"lineByLine": "true",
66+
"removeUnmatched": "false",
67+
"dataOriginDate": "",
68+
"skipSnapshot": "false"
69+
}
70+
api_instance.add_file_tasks_to_challenge(test_geojson, test_challenge_id)
71+
mock_request.assert_called_once_with(
72+
f'{self.url}/challenge/12978/addFileTasks',
73+
files=data,
74+
params=query_params)
75+
6076
@patch('maproulette.api.maproulette_server.requests.Session.post')
6177
def test_create_virtual_challenge(self, mock_request, api_instance=api):
6278
# TODO: add model for virtual challenge to aid in posting

tests/test_task_api.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,18 @@ def test_get_task_history(self, mock_request, api_instance=api):
2626
f'{self.url}/task/{test_task_id}/history',
2727
params=None)
2828

29+
@patch('maproulette.api.maproulette_server.requests.Session.post')
30+
def test_create_task(self, mock_request, api_instance=api):
31+
geometries = test_geojson['features'][0]['geometry']
32+
test_task_model = maproulette.TaskModel(name='test_task',
33+
parent='12345',
34+
geometries=geometries)
35+
api_instance.create_task(test_task_model)
36+
mock_request.assert_called_once_with(
37+
f'{self.url}/task',
38+
json=test_task_model.to_dict(),
39+
params=None)
40+
2941
@patch('maproulette.api.maproulette_server.requests.Session.post')
3042
def test_create_tasks(self, mock_request, api_instance=api):
3143
test_tasks = []
@@ -77,7 +89,7 @@ def test_create_cooperative_task(self, mock_request, api_instance=api):
7789
api_instance.create_task(test_task)
7890
mock_request.assert_called_once_with(
7991
f'{self.url}/task',
80-
json=test_task,
92+
json=test_task.to_dict(),
8193
params=None)
8294

8395
@patch('maproulette.api.maproulette_server.requests.Session.put')

tox.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[tox]
2-
envlist = py36
2+
minversion = 3.6.0
33

44
[testenv]
55
deps =

0 commit comments

Comments
 (0)