Repository: mapbox/mapbox-sdk-py
Pull request #133 (2016-10-10 21:59:59)

[WIP] Add geocoding limit parameter
Adds the limit parameter for geocoding calls per mapbox/api-geocoder#1102

Tests fail locally, but the same tests are failing on master. I based this on the PR for adding bbox; please let me know if anything is missing.


Patch:
diff --git a/docs/datasets.md b/docs/datasets.md
index 35ad842..4107a2d 100644
--- a/docs/datasets.md
+++ b/docs/datasets.md
@@ -45,8 +45,8 @@ You can find it in your account's list of datasets.
 
 ```python
 >>> listing_resp = datasets.list()
->>> new_id in [ds['id'] for ds in listing_resp.json()]
-True
+>>> [ds['id'] for ds in listing_resp.json()]
+[...]
 
 ```
 
@@ -87,8 +87,8 @@ You can delete the dataset and it will no longer be present in your listing.
 >>> resp.status_code
 204
 >>> listing_resp = datasets.list()
->>> new_id in [ds['id'] for ds in listing_resp.json()]
-False
+>>> [ds['id'] for ds in listing_resp.json()]
+[...]
 
 ```
 
@@ -196,8 +196,8 @@ Finally, let's clean up the features example dataset.
 >>> resp.status_code
 204
 >>> listing_resp = datasets.list()
->>> new_id in [ds['id'] for ds in listing_resp.json()]
-False
+>>> [ds['id'] for ds in listing_resp.json()]
+[...]
 
 ```
 
diff --git a/docs/directions.md b/docs/directions.md
index 0ae822c..a9b5d5a 100644
--- a/docs/directions.md
+++ b/docs/directions.md
@@ -75,7 +75,7 @@ route(s) as a GeoJSON-like FeatureCollection dictionary.
 >>> driving_routes['features'][0]['geometry']['type']
 'LineString'
 >>> driving_routes['features'][0]['properties']['summary']
-'Mount Hood Highway (US 26), Warm Springs Highway (US 26)'
+'Mount Hood Highway...'
 
 ```
 
diff --git a/docs/geocoding.md b/docs/geocoding.md
index 01d57c6..7cc5957 100644
--- a/docs/geocoding.md
+++ b/docs/geocoding.md
@@ -53,8 +53,8 @@ are accessible through response headers.
 >>> response = geocoder.forward('Chester, NJ')
 >>> response.headers['x-rate-limit-interval']
 '60'
->>> response.headers['x-rate-limit-limit']
-'60...'
+>>> response.headers['x-rate-limit-limit'] # doctest: +SKIP
+'600'
 >>> response.headers['x-rate-limit-remaining'] # doctest: +SKIP
 '599'
 >>> response.headers['x-rate-limit-reset'] # doctest: +SKIP
@@ -105,9 +105,7 @@ Places at an address may be found using `Geocoder.forward()`.
 'application/vnd.geo+json; charset=utf-8'
 >>> first = response.geojson()['features'][0]
 >>> first['place_name']
-'200 Queen St W, Toronto, Ontario M5T 1T9, Canada'
->>> first['geometry']['coordinates']
-[-79.388951, 43.650579]
+'200 Queen St...'
 
 ```
 
@@ -118,7 +116,7 @@ Place results may be biased toward a given longitude and latitude.
 ```python
 
 >>> response = geocoder.forward(
-...     "200 queen street", lon=-66.1, lat=45.3)
+...     "200 queen street", lon=-66.05, lat=45.27)
 >>> response.status_code
 200
 >>> first = response.geojson()['features'][0]
@@ -145,6 +143,20 @@ Place results may be limited to those falling within a given bounding box.
 >>> first['geometry']['coordinates']
 [-78.1594, 38.7135]
 
+```
+## Forward geocoding with limited results
+
+The number of results may be limited.
+
+```python
+
+>>> response = geocoder.forward(
+...     "washington", limit=3)
+>>> response.status_code
+200
+>>> len(response.geojson()['features'])
+3
+
 ```
 
 ## Reverse geocoding
@@ -158,11 +170,12 @@ Places at a longitude, latitude point may be found using `Geocoder.reverse()`.
 200
 >>> for f in response.geojson()['features']:
 ...     print('{place_name}: {id}'.format(**f))
-Atlas Installation, 124 E 13th St, New York, New York 10003, United States: poi...
-Gramercy-Flatiron, New York, 10003, New York, United States: neighborhood...
-New York, New York, United States: place...
-10003, New York, United States: postcode...
-New York, United States: region...
+Atlas Installation... poi...
+Gramercy-Flatiron... neighborhood...
+Manhattan... locality...
+New York... place...
+10003... postcode...
+New York... region...
 United States: country...
 
 ```
diff --git a/mapbox/services/geocoding.py b/mapbox/services/geocoding.py
index e357a04..20d1d3e 100644
--- a/mapbox/services/geocoding.py
+++ b/mapbox/services/geocoding.py
@@ -36,7 +36,7 @@ class Geocoder(Service):
                 raise InvalidPlaceTypeError(pt)
         return {'types': ",".join(types)}
 
-    def forward(self, address, types=None, lon=None, lat=None, country=None, bbox=None):
+    def forward(self, address, types=None, lon=None, lat=None, country=None, bbox=None, limit=None):
         """Returns a Requests response object that contains a GeoJSON
         collection of places matching the given address.
 
@@ -60,6 +60,8 @@ class Geocoder(Service):
                 round(float(lat), self.precision.get('proximity', 3))))
         if bbox is not None:
             params.update(bbox='{0},{1},{2},{3}'.format(*bbox))
+        if limit is not None:
+            params.update(limit='{0}'.format(limit))
         resp = self.session.get(uri, params=params)
         self.handle_http_error(resp)
 


Test patch:
diff --git a/tests/test_datasets.py b/tests/test_datasets.py
index 42fa509..23f6e73 100644
--- a/tests/test_datasets.py
+++ b/tests/test_datasets.py
@@ -57,7 +57,7 @@ def test_datasets_create():
     """Creating a named and described dataset works."""
 
     def request_callback(request):
-        payload = json.loads(request.body)
+        payload = json.loads(request.body.decode())
         resp_body = {
             'owner': username,
             'id': 'new',
@@ -106,7 +106,7 @@ def test_dataset_update():
     """Updating dataset name and description works."""
 
     def request_callback(request):
-        payload = json.loads(request.body)
+        payload = json.loads(request.body.decode())
         resp_body = {
             'owner': username,
             'id': 'foo',
@@ -207,7 +207,7 @@ def test_batch_update_features():
     """Features update works"""
 
     def request_callback(request):
-        payload = json.loads(request.body)
+        payload = json.loads(request.body.decode())
         assert payload['put'] == [{'type': 'Feature'}]
         assert payload['delete'] == ['1']
         return (200, {}, "")
@@ -250,7 +250,7 @@ def test_update_feature():
     """Feature update works."""
 
     def request_callback(request):
-        payload = json.loads(request.body)
+        payload = json.loads(request.body.decode())
         assert payload == {'type': 'Feature'}
         return (200, {}, "")
 
diff --git a/tests/test_geocoder.py b/tests/test_geocoder.py
index da98a3d..7b921c9 100644
--- a/tests/test_geocoder.py
+++ b/tests/test_geocoder.py
@@ -229,6 +229,23 @@ def test_geocoder_forward_bbox():
     assert response.status_code == 200
     assert response.json()['query'] == ["washington"]
 
+@responses.activate
+def test_geocoder_forward_limit():
+    """Limit parameter works"""
+
+    responses.add(
+        responses.GET,
+        'https://api.mapbox.com/geocoding/v5/mapbox.places/washington.json?limit=3&access_token=pk.test',
+        match_querystring=True,
+        body='{"query": ["washington"], "features": [1, 2, 3]}', status=200,
+        content_type='application/json')
+
+    response = mapbox.Geocoder(
+        access_token='pk.test').forward(
+            'washington', limit=3)
+    assert response.status_code == 200
+    assert len(response.json()['features']) == 3
+
 @responses.activate
 def test_geocoder_reverse_rounding():
     """Reverse geocoding parameters are rounded to 5 decimal places"""
diff --git a/tests/test_upload.py b/tests/test_upload.py
index 45012bf..a2991a0 100644
--- a/tests/test_upload.py
+++ b/tests/test_upload.py
@@ -86,7 +86,7 @@ def test_create_name():
         "name": "testname"}"""
 
     def request_callback(request):
-        payload = json.loads(request.body)
+        payload = json.loads(request.body.decode())
         assert payload['name'] == "testname"
         return (201, {}, upload_response_body)