Skip to content

Commit 1de066f

Browse files
committed
Added new batch functionality
1 parent a01f905 commit 1de066f

5 files changed

Lines changed: 28 additions & 53 deletions

File tree

maproulette/api/challenge.py

Lines changed: 0 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
"""This module contains the methods that the user will use directly to interact with MapRoulette challenges"""
22

3-
import geojson
43
from maproulette.api.maproulette_server import MapRouletteServer
54
from maproulette.models.challenge import ChallengeModel
65

@@ -260,42 +259,6 @@ def add_tasks_to_challenge(self, data, challenge_id):
260259
body=data)
261260
return response
262261

263-
def add_tasks_to_challenge_batch(self, data, challenge_id, batch_size=100):
264-
"""Method to add tasks to an existing challenge
265-
266-
:param data: a GeoJSON containing geometry of tasks to be added to a challenge
267-
:param challenge_id: the ID corresponding to the challenge that tasks will be added to
268-
:param batch_size: the number of features within the GeoJSON to send to the API at a time. Default is 100.
269-
:returns: the API response from the PUT request
270-
"""
271-
if isinstance(data, str):
272-
try:
273-
geojson.loads(data)
274-
except ValueError
275-
features = data['features']
276-
feature_collection = {'type': 'FeatureCollection'}
277-
remaining_features = len(features)
278-
bundle = []
279-
count = 0
280-
for index, feature in enumerate(features):
281-
bundle.append(feature)
282-
count += 1
283-
if count == batch_size:
284-
feature_collection['features'] = bundle
285-
self.add_tasks_to_challenge(
286-
challenge_id=challenge_id,
287-
data=feature_collection
288-
)
289-
remaining_features -= count
290-
bundle = []
291-
count = 0
292-
if remaining_features > 0:
293-
feature_collection['features'] = bundle
294-
self.add_tasks_to_challenge(
295-
challenge_id=challenge_id,
296-
data=feature_collection
297-
)
298-
299262
def delete_challenge(self, challenge_id, immediate="false"):
300263
"""Method to delete a challenge by using the corresponding challenge ID
301264
@@ -351,11 +314,3 @@ def is_challenge_model(input_object):
351314
:returns: True if instance of model
352315
"""
353316
return bool(isinstance(input_object, ChallengeModel))
354-
355-
@staticmethod
356-
def string_to_geojson(input_object):
357-
"""Converts string to GeoJSON object using the geojson package
358-
359-
:param input_object: string representing the GeoJSON object
360-
:return: a valid
361-
"""

maproulette/api/task.py

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,20 @@ def get_task_history(self, task_id):
3030
endpoint=f"/task/{task_id}/history")
3131
return response
3232

33-
def create_tasks(self, data):
34-
"""Method to create a batch of tasks
33+
def create_tasks(self, data, batch_size=100):
34+
"""Method to create a batch of tasks using the specified batch_size.
3535
3636
:param data: a JSON input containing task details
37+
:param batch_size: the number of tasks to post per API call. The default is 100.
38+
:type batch_size: int
3739
:returns: the API response from the POST request
3840
"""
39-
response = self.post(
40-
endpoint="/tasks",
41-
body=data)
41+
response = []
42+
for batch in self.batch_generator(input_list=data, chunk_size=batch_size):
43+
response.append(self.post(
44+
endpoint="/tasks",
45+
body=batch)
46+
)
4247
return response
4348

4449
def update_tasks(self, data):
@@ -157,3 +162,15 @@ def is_task_model(input_object):
157162
:returns: True if instance of model
158163
"""
159164
return bool(isinstance(input_object, TaskModel))
165+
166+
@staticmethod
167+
def batch_generator(input_list, chunk_size):
168+
"""Method to yield successive n-sized chunks from input_list
169+
170+
:param input_list: the list to break into chunks
171+
:param chunk_size: the number of list items to include per chunk
172+
:type chunk_size: int
173+
:returns: an iterator for the n-sized chunks of the input_list
174+
"""
175+
for i in range(0, len(input_list), chunk_size):
176+
yield input_list[i:i + chunk_size]

maproulette/models/task.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ def to_dict(self):
190190
"id": self._id,
191191
"name": self._name,
192192
"parent": self._parent,
193+
"geometries": self._geometries,
193194
"instruction": self._instruction,
194195
"location": self._location,
195196
"suggestedFix": self._suggested_fix,

requirements.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,3 @@ requests==2.23.0
22
tox==3.14.5
33
sphinx==2.4.4
44
sphinx_rtd_theme
5-
geojson

tests/test_task_api.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,16 @@ def test_get_task_history(self, mock_request, api_instance=api):
2626

2727
@patch('maproulette.api.maproulette_server.requests.Session.post')
2828
def test_create_tasks(self, mock_request, api_instance=api):
29+
test_tasks = []
2930
geometries = test_geojson['features'][0]['geometry']
3031
test_task_model = maproulette.TaskModel(name='test_task',
3132
parent='12345',
3233
geometries=geometries)
34+
test_tasks.append(test_task_model.to_dict())
3335
mock_request.return_value.status_code = '200'
34-
response = api_instance.create_tasks(test_task_model)
35-
self.assertEqual(response['status'], '200')
36+
responses = api_instance.create_tasks(test_tasks)
37+
for response in responses:
38+
self.assertEqual(response['status'], '200')
3639

3740
@patch('maproulette.api.maproulette_server.requests.Session.put')
3841
def test_update_tasks(self, mock_request, api_instance=api):

0 commit comments

Comments
 (0)