Repository: mapbox/mapbox-sdk-py
Pull request #271 (2019-03-05 17:08:23)

add bypass flag for uploads service
Adds a flag alongside patch for bypassing mbtiles uploads (which requires the feature to be enabled on a user's account).

cc @ivovandongen @ian29 @sgillies 


Patch:
diff --git a/CHANGES b/CHANGES
index 0a525bc..80dffea 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,7 +1,11 @@
 Changes
 =======
 
-0.17.2 (2019-11-30)
+0.18.0 (2019-03-05)
+-------------------
+- Added support for bypass_mbtiles_validation flag in the Uploads API (#271)
+
+0.17.2 (2018-11-30)
 -------------------
 
 Bug fixes:
@@ -41,7 +45,7 @@ New features:
 - Added support for Directions v5 (#203).
 - The Mapbox Distance API is no more and the distance module has been deleted
   (#232). Users must use the DirectionsMatrix introduced in 0.15.
-- Project documentation is now on Read the Docs: 
+- Project documentation is now on Read the Docs:
   https://mapbox-mapbox.readthedocs-hosted.com/en/latest/.
 
 0.15.1 (2018-01-16)
diff --git a/mapbox/__init__.py b/mapbox/__init__.py
index cc1e810..5431645 100644
--- a/mapbox/__init__.py
+++ b/mapbox/__init__.py
@@ -1,5 +1,5 @@
 # mapbox
-__version__ = "0.17.2"
+__version__ = "0.18.0"
 
 from .services.datasets import Datasets
 from .services.directions import Directions
diff --git a/mapbox/services/uploads.py b/mapbox/services/uploads.py
index d6077bf..722fc38 100644
--- a/mapbox/services/uploads.py
+++ b/mapbox/services/uploads.py
@@ -116,7 +116,7 @@ class Uploader(Service):
 
         return creds['url']
 
-    def create(self, stage_url, tileset, name=None, patch=False):
+    def create(self, stage_url, tileset, name=None, patch=False, bypass=False):
         """Create a tileset
 
         Note: this step is refered to as "upload" in the API docs;
@@ -144,6 +144,9 @@ class Uploader(Service):
         patch: bool
             Optional patch mode which requires a flag on the owner's
             account.
+        bypass: bool
+            Optional bypass validation mode for MBTiles which requires
+            a flag on the owner's account.
 
         Returns
         -------
@@ -158,6 +161,9 @@ class Uploader(Service):
         if patch:
             msg['patch'] = patch
 
+        if bypass:
+            msg['bypass_mbtiles_validation'] = bypass
+
         msg['name'] = name if name else _name
 
         uri = URITemplate(self.baseuri + '/{username}').expand(
@@ -246,7 +252,7 @@ class Uploader(Service):
         self.handle_http_error(resp)
         return resp
 
-    def upload(self, fileobj, tileset, name=None, patch=False, callback=None):
+    def upload(self, fileobj, tileset, name=None, patch=False, callback=None, bypass=False):
         """Upload data and create a Mapbox tileset
 
         Effectively replicates the Studio upload feature. Returns a
@@ -265,6 +271,9 @@ class Uploader(Service):
         patch: bool
             Optional patch mode which requires a flag on the owner's
             account.
+        bypass: bool
+            Optional bypass validation mode for MBTiles which requires
+            a flag on the owner's account.
         callback: func
             A function that takes a number of bytes processed as its
             sole argument. May be used with a progress bar.
@@ -275,4 +284,4 @@ class Uploader(Service):
         """
         tileset = self._validate_tileset(tileset)
         url = self.stage(fileobj, callback=callback)
-        return self.create(url, tileset, name=name, patch=patch)
+        return self.create(url, tileset, name=name, patch=patch, bypass=bypass)


Test patch:
diff --git a/tests/test_upload.py b/tests/test_upload.py
index b802c38..43df3b6 100644
--- a/tests/test_upload.py
+++ b/tests/test_upload.py
@@ -431,6 +431,51 @@ def test_upload_patch(monkeypatch):
     assert job['tileset'] == "{0}.test1".format(username)
 
 
+@responses.activate
+def test_upload_bypass(monkeypatch):
+    """Upload a file and create a tileset bypassing mbtiles validation"""
+
+    monkeypatch.setattr(mapbox.services.uploads, 'boto3_session', MockSession)
+
+    def ensure_bypass(request):
+        payload = json.loads(request.body.decode())
+        assert payload['bypass_mbtiles_validation']
+        headers = {}
+        return (201, headers, upload_response_body)
+
+    # Credentials
+    query_body = """
+       {{"key": "_pending/{username}/key.test",
+         "accessKeyId": "ak.test",
+         "bucket": "tilestream-tilesets-production",
+         "url": "https://tilestream-tilesets-production.s3.amazonaws.com/_pending/{username}/key.test",
+         "secretAccessKey": "sak.test",
+         "sessionToken": "st.test"}}""".format(username=username)
+
+    responses.add(
+        responses.POST,
+        'https://api.mapbox.com/uploads/v1/{0}/credentials?access_token={1}'.format(
+            username, access_token),
+        match_querystring=True,
+        body=query_body, status=200,
+        content_type='application/json')
+
+    responses.add_callback(
+        responses.POST,
+        'https://api.mapbox.com/uploads/v1/{0}?access_token={1}'.format(username, access_token),
+        callback=ensure_bypass,
+        match_querystring=True,
+        content_type='application/json')
+
+    with open('tests/moors.json', 'rb') as src:
+        res = mapbox.Uploader(access_token=access_token).upload(
+            src, 'testuser.Test1', name='test1', bypass=True)
+
+    assert res.status_code == 201
+    job = res.json()
+    assert job['tileset'] == "{0}.test1".format(username)
+
+
 def test_upload_tileset_validation():
     with pytest.raises(mapbox.errors.ValidationError):
         with open('tests/moors.json', 'rb') as src: