sgillies: 👋  @amishas157 @perrygeo can you review this for me?
diff --git a/.travis.yml b/.travis.yml
index b8e7592..ff98592 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -6,7 +6,7 @@ python:
   - '3.4'
   - '3.5'
   - '3.6'
-  - pypy
+  - pypy-5.3.1
 cache:
   directories:
     - $HOME/.pip-cache/
diff --git a/CHANGES b/CHANGES
index ee8f2dd..9a18eff 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,8 @@
+Next (YYYY-MM-DD)
+-----------------
+- Add api_name and api_version class attributes (#207).
+
+
 0.14.0 (2017-07-10)
 -------------------
 - Permit images of size 1 and 1280 (#196)
diff --git a/README.rst b/README.rst
index d5e4771..fc69108 100644
--- a/README.rst
+++ b/README.rst
@@ -15,56 +15,57 @@ The Mapbox Python SDK is a low-level client API, not a Resource API such as the
 Services
 ========
 
-- **Analytics** `examples <./docs/analytics.md>`__, `website <https://www.mapbox.com/api-documentation/#analytics>`__
+- **Analytics V1** `examples <./docs/analytics.md>`__, `website <https://www.mapbox.com/api-documentation/#analytics>`__
 
   - API usage for services by resource. 
   - available for premium and enterprise plans.
 
-- **Directions** `examples <./docs/directions.md#directions>`__, `website <https://www.mapbox.com/api-documentation/?language=Python#directions>`__
+- **Directions V4** `examples <./docs/directions.md#directions>`__, `website <https://www.mapbox.com/api-documentation/?language=Python#directions>`__
 
   - Profiles for driving, walking, and cycling
   - GeoJSON & Polyline formatting
   - Instructions as text or HTML
 
-- **Distance** `examples <./docs/distance.md#distance>`__, `website <https://www.mapbox.com/api-documentation/?language=Python#directions-matrix>`__
+- **Distance V1** `examples <./docs/distance.md#distance>`__, `website <https://www.mapbox.com/api-documentation/?language=Python#directions-matrix>`__
 
   - Travel-time tables between up to 100 points
   - Profiles for driving, walking and cycling
 
-- **Geocoding** `examples <./docs/geocoding.md#geocoding>`__, `website <https://www.mapbox.com/api-documentation/?language=Python#geocoding>`__
+- **Geocoding V5** `examples <./docs/geocoding.md#geocoding>`__, `website <https://www.mapbox.com/api-documentation/?language=Python#geocoding>`__
 
   - Forward (place names ⇢ longitude, latitude)
   - Reverse (longitude, latitude ⇢ place names)
 
-- **Map Matching** `examples <./docs/mapmatching.md#map-matching>`__, `website <https://www.mapbox.com/api-documentation/?language=Python#map-matching>`__
+- **Map Matching V4** `examples <./docs/mapmatching.md#map-matching>`__, `website <https://www.mapbox.com/api-documentation/?language=Python#map-matching>`__
 
   - Snap GPS traces to OpenStreetMap data
 
-- **Static Maps** `examples <./docs/static.md#static-maps>`__, `website <https://www.mapbox.com/api-documentation/pages/static_classic.html>`__
+- **Static Maps V4** `examples <./docs/static.md#static-maps>`__, `website <https://www.mapbox.com/api-documentation/pages/static_classic.html>`__
 
   - Generate standalone images from existing Mapbox *mapids* (tilesets)
   - Render with GeoJSON overlays
   
-- **Static Styles** `examples <./docs/static.md#static-maps>`__, `website <https://www.mapbox.com/api-documentation/#static>`__
+- **Static Styles V1** `examples <./docs/static.md#static-maps>`__, `website <https://www.mapbox.com/api-documentation/#static>`__
 
   - Generate standalone images from existing Mapbox *styles*
   - Render with GeoJSON overlays
   - Adjust pitch and bearing, decimal zoom levels
   
-- **Surface** `examples <./docs/surface.md#surface>`__, `website <https://www.mapbox.com/developers/api/surface/>`__
+- **Surface V4** `examples <./docs/surface.md#surface>`__, `website <https://www.mapbox.com/developers/api/surface/>`__
 
   - Interpolates values along lines. Useful for elevation traces.
 
-- **Uploads** `examples <./docs/uploads.md#uploads>`__, `website <https://www.mapbox.com/api-documentation/?language=Python#uploads>`__
+- **Uploads V1** `examples <./docs/uploads.md#uploads>`__, `website <https://www.mapbox.com/api-documentation/?language=Python#uploads>`__
 
   - Upload data to be processed and hosted by Mapbox.
 
-- **Datasets** `examples <./docs/datasets.md#datasets>`__, `website <https://www.mapbox.com/api-documentation/?language=Python#datasets>`__
+- **Datasets V1** `examples <./docs/datasets.md#datasets>`__, `website <https://www.mapbox.com/api-documentation/?language=Python#datasets>`__
 
   - Manage editable collections of GeoJSON features
   - Persistent storage for custom geographic data
 
-Other services coming soon.
+Please note that there may be some lag between the release of new Mapbox web
+services and releases of this package.
 
 Installation
 ============
diff --git a/mapbox/services/analytics.py b/mapbox/services/analytics.py
index dafb3c5..5428b70 100644
--- a/mapbox/services/analytics.py
+++ b/mapbox/services/analytics.py
@@ -5,15 +5,14 @@ from uritemplate import URITemplate
 from mapbox.services.base import Service
 from mapbox import errors
 
+
 class Analytics(Service):
-    """Access to Analytics API"""
+    """Access to Analytics API V1"""
 
+    api_name = 'analytics'
+    api_version = 'v1'
     valid_resource_types = ['tokens', 'styles', 'accounts', 'tilesets']
 
-    @property
-    def baseuri(self):
-        return 'https://{0}/analytics/v1'.format(self.host)
-
     def _validate_resource_type(self, resource_type):
         if resource_type not in self.valid_resource_types:
             raise errors.InvalidResourceTypeError(
diff --git a/mapbox/services/base.py b/mapbox/services/base.py
index 9bae0a4..c8cae87 100644
--- a/mapbox/services/base.py
+++ b/mapbox/services/base.py
@@ -42,6 +42,8 @@ class Service(object):
     """Service base class."""
 
     default_host = 'api.mapbox.com'
+    api_name = 'hors service'
+    api_version = 'v0'
 
     def __init__(self, access_token=None, host=None, cache=None):
         """Constructs a Service object.
@@ -55,6 +57,11 @@ class Service(object):
         if cache:
             self.session = CacheControl(self.session, cache=cache)
 
+    @property
+    def baseuri(self):
+        return 'https://{0}/{1}/{2}'.format(
+            self.host, self.api_name, self.api_version)
+
     @property
     def username(self):
         """Get username from access token.
diff --git a/mapbox/services/datasets.py b/mapbox/services/datasets.py
index 921897b..064f27e 100644
--- a/mapbox/services/datasets.py
+++ b/mapbox/services/datasets.py
@@ -8,11 +8,10 @@ from mapbox.services.base import Service
 
 
 class Datasets(Service):
-    """Access to the Datasets API."""
+    """Access to the Datasets API V1"""
 
-    @property
-    def baseuri(self):
-        return 'https://{0}/datasets/v1'.format(self.host)
+    api_name = 'datasets'
+    api_version = 'v1'
 
     def _attribs(self, name=None, description=None):
         """Form an attributes dictionary from keyword args."""
diff --git a/mapbox/services/directions.py b/mapbox/services/directions.py
index d6f6af3..a782c33 100644
--- a/mapbox/services/directions.py
+++ b/mapbox/services/directions.py
@@ -6,7 +6,10 @@ from mapbox import errors
 
 
 class Directions(Service):
-    """Access to the Directions API."""
+    """Access to the Directions API V4"""
+
+    api_name = 'directions'
+    api_version = 'v4'
 
     valid_profiles = ['mapbox.driving',
                       'mapbox.cycling',
@@ -16,7 +19,8 @@ class Directions(Service):
 
     @property
     def baseuri(self):
-        return 'https://{0}/v4/directions'.format(self.host)
+        return 'https://{0}/{2}/{1}'.format(
+            self.host, self.api_name, self.api_version)
 
     def _validate_profile(self, profile):
         if profile not in self.valid_profiles:
diff --git a/mapbox/services/distance.py b/mapbox/services/distance.py
index be27a34..9362532 100644
--- a/mapbox/services/distance.py
+++ b/mapbox/services/distance.py
@@ -6,13 +6,17 @@ from mapbox.services.base import Service
 
 
 class Distance(Service):
-    """Access to the Distance API."""
+    """Access to the Distance API V1"""
+
+    api_name = 'distances'
+    api_version = 'v1'
 
     valid_profiles = ['driving', 'cycling', 'walking']
 
     @property
     def baseuri(self):
-        return 'https://{0}/distances/v1/mapbox'.format(self.host)
+        return 'https://{0}/{1}/{2}/mapbox'.format(
+            self.host, self.api_name, self.api_version)
 
     def _validate_profile(self, profile):
         if profile not in self.valid_profiles:
diff --git a/mapbox/services/geocoding.py b/mapbox/services/geocoding.py
index e22b91e..bad7dd3 100644
--- a/mapbox/services/geocoding.py
+++ b/mapbox/services/geocoding.py
@@ -7,14 +7,12 @@ from mapbox.services.base import Service
 
 
 class Geocoder(Service):
-    """Access to the Geocoding API."""
+    """Access to the Geocoding API V5"""
 
+    api_name = 'geocoding'
+    api_version = 'v5'
     precision = {'reverse': 5, 'proximity': 3}
 
-    @property
-    def baseuri(self):
-        return 'https://{0}/geocoding/v5'.format(self.host)
-
     def __init__(self, name='mapbox.places', access_token=None, cache=None,
                  host=None):
         """Constructs a Geocoding Service object.
diff --git a/mapbox/services/mapmatching.py b/mapbox/services/mapmatching.py
index cec6acc..66f6c8f 100644
--- a/mapbox/services/mapmatching.py
+++ b/mapbox/services/mapmatching.py
@@ -7,14 +7,12 @@ from mapbox.services.base import Service
 
 
 class MapMatcher(Service):
-    """Access to the Map Matching API."""
+    """Access to the Map Matching API V4"""
 
+    api_name = 'matching'
+    api_version = 'v4'
     valid_profiles = ['mapbox.driving', 'mapbox.cycling', 'mapbox.walking']
 
-    @property
-    def baseuri(self):
-        return 'https://{0}/matching/v4'.format(self.host)
-
     def _validate_profile(self, profile):
         if profile not in self.valid_profiles:
             raise errors.InvalidProfileError(
diff --git a/mapbox/services/static.py b/mapbox/services/static.py
index a532ac4..4aadee7 100644
--- a/mapbox/services/static.py
+++ b/mapbox/services/static.py
@@ -8,11 +8,14 @@ from mapbox.utils import normalize_geojson_featurecollection
 
 
 class Static(Service):
-    """Access to the Static Map API."""
+    """Access to the Static Map API V4"""
+
+    api_name = None
+    api_version = 'v4'
 
     @property
     def baseuri(self):
-        return 'https://{0}/v4'.format(self.host)
+        return 'https://{0}/{1}'.format(self.host, self.api_version)
 
     def _validate_lat(self, val):
         if val < -85.0511 or val > 85.0511:
diff --git a/mapbox/services/static_style.py b/mapbox/services/static_style.py
index b0cef3a..750f0fa 100644
--- a/mapbox/services/static_style.py
+++ b/mapbox/services/static_style.py
@@ -50,11 +50,10 @@ def validate_bearing(val):
 
 
 class StaticStyle(Service):
-    """Access to the Static Map API."""
+    """Access to the Static Map API V1"""
 
-    @property
-    def baseuri(self):
-        return 'https://{0}/styles/v1'.format(self.host)
+    api_name = 'styles'
+    api_version = 'v1'
 
     def tile(self, username, style_id, z, x, y, tile_size=512, retina=False):
         "/styles/v1/{username}/{style_id}/tiles/{tileSize}/{z}/{x}/{y}{@2x}"
diff --git a/mapbox/services/surface.py b/mapbox/services/surface.py
index 8c69073..2dd3dcc 100644
--- a/mapbox/services/surface.py
+++ b/mapbox/services/surface.py
@@ -5,11 +5,15 @@ from mapbox.services.base import Service
 
 
 class Surface(Service):
-    """Access to the Surface API."""
+    """Access to the Surface API V4"""
+
+    api_name = 'surface'
+    api_version = 'v4'
 
     @property
     def baseuri(self):
-        return 'https://{0}/v4/surface'.format(self.host)
+        return 'https://{0}/{2}/{1}'.format(
+            self.host, self.api_name, self.api_version)
 
     def surface(self,
                 features,
diff --git a/mapbox/services/uploads.py b/mapbox/services/uploads.py
index 8c4a34d..94dcd75 100644
--- a/mapbox/services/uploads.py
+++ b/mapbox/services/uploads.py
@@ -10,7 +10,7 @@ from mapbox.services.base import Service
 
 
 class Uploader(Service):
-    """Access to the Upload API.
+    """Access to the Upload API V1
 
     Example usage:
 
@@ -29,9 +29,8 @@ class Uploader(Service):
         assert job not in u.list().json()
     """
 
-    @property
-    def baseuri(self):
-        return 'https://{0}/uploads/v1'.format(self.host)
+    api_name = 'uploads'
+    api_version = 'v1'
 
     def _get_credentials(self):
         """Gets temporary S3 credentials to stage user-uploaded files
diff --git a/tox.ini b/tox.ini
index bdce644..bceb578 100644
--- a/tox.ini
+++ b/tox.ini
@@ -7,4 +7,4 @@ deps =
     pytest-cov
     responses
 commands = 
-    py.test --cov {envsitepackagesdir}/mapbox --cov-report term-missing
+    py.test --cov mapbox --cov-report term-missing

Add api_name and api_version Service class attributes
These can be used in constructing the the base URI and in debugging.
diff --git a/tests/test_analytics.py b/tests/test_analytics.py
index 0940e41..1ddd84e 100644
--- a/tests/test_analytics.py
+++ b/tests/test_analytics.py
@@ -5,25 +5,37 @@ import responses
 import mapbox
 from mapbox import errors
 
+
+def test_class_attrs():
+    """Get expected class attr values"""
+    serv = mapbox.Analytics()
+    assert serv.api_name == 'analytics'
+    assert serv.api_version == 'v1'
+
+
 def test_resource_type_invalid():
     """'random' is not a valid resource type."""
     with pytest.raises(errors.InvalidResourceTypeError):
         mapbox.Analytics(access_token='pk.test')._validate_resource_type('random')
 
+
 @pytest.mark.parametrize('resource_type', ['tokens', 'styles', 'accounts', 'tilesets'])
 def test_profile_valid(resource_type):
     """Resource types are valid."""
     assert resource_type == mapbox.Analytics(
         access_token='pk.test')._validate_resource_type(resource_type)
 
+
 @pytest.mark.parametrize(
-    'start, end',[('2016-03-22T00:00:00.000Z', None),
-                ('2016-03-22T00:00:00.000Z', '2016-03-20T00:00:00.000Z'),
-                ('2016-03-22T00:00:00.000Z', '2017-04-20T00:00:00.000Z')])
+    'start, end', [
+        ('2016-03-22T00:00:00.000Z', None),
+        ('2016-03-22T00:00:00.000Z', '2016-03-20T00:00:00.000Z'),
+        ('2016-03-22T00:00:00.000Z', '2017-04-20T00:00:00.000Z')])
 def test_period_invalid(start, end):
     with pytest.raises(errors.InvalidPeriodError):
         mapbox.Analytics(access_token='pk.test')._validate_period(start, end)
 
+
 @pytest.mark.parametrize(
     'start, end', [('2016-03-22T00:00:00.000Z', '2016-03-24T00:00:00.000Z'),
                    (None, None)])
@@ -31,16 +43,19 @@ def test_period_valid(start, end):
     period = start, end
     assert period == mapbox.Analytics(access_token='pk.test')._validate_period(start, end)
 
+
 def test_username_invalid():
     """Username is requird."""
     with pytest.raises(errors.InvalidUsernameError):
         mapbox.Analytics(access_token='pk.test')._validate_username(None)
 
+
 def test_username_valid():
     """Providing valid username"""
     user = 'abc'
     assert user == mapbox.Analytics(access_token='pk.test')._validate_username(user)
 
+
 def test_id_invalid():
     """id is required when resource type is other than accounts"""
     resource_type = 'tokens'
@@ -48,13 +63,14 @@ def test_id_invalid():
     with pytest.raises(errors.InvalidId):
         mapbox.Analytics(access_token='pk.test')._validate_id(resource_type, id)
 
+
 @pytest.mark.parametrize(
-    'resource_type, id', [('accounts', None),
-                   ('tokens', 'abc')])
+    'resource_type, id', [('accounts', None), ('tokens', 'abc')])
 def test_id_valid(resource_type, id):
     """id is not required when resource type is accounts"""
     assert id == mapbox.Analytics(access_token='pk.test')._validate_id(resource_type, id)
 
+
 @responses.activate
 def test_analytics():
     responses.add(
diff --git a/tests/test_base.py b/tests/test_base.py
index 2025043..da442ad 100644
--- a/tests/test_base.py
+++ b/tests/test_base.py
@@ -10,6 +10,14 @@ from mapbox.errors import TokenError
 from mapbox.services import base
 
 
+def test_class_attrs():
+    """Get expected class attr values"""
+    serv = base.Service()
+    assert serv.api_name == 'hors service'
+    assert serv.api_version == 'v0'
+    assert serv.baseuri == 'https://api.mapbox.com/hors service/v0'
+
+
 def test_service_session():
     """Get a session using a token"""
     session = base.Session('pk.test')
diff --git a/tests/test_datasets.py b/tests/test_datasets.py
index b35f517..53a4e0c 100644
--- a/tests/test_datasets.py
+++ b/tests/test_datasets.py
@@ -11,6 +11,13 @@ access_token = 'pk.{0}.test'.format(
     base64.b64encode(b'{"u":"testuser"}').decode('utf-8'))
 
 
+def test_class_attrs():
+    """Get expected class attr values"""
+    serv = Datasets()
+    assert serv.api_name == 'datasets'
+    assert serv.api_version == 'v1'
+
+
 def test_datasets_service_properties():
     """Get expected username and baseuri."""
     datasets = Datasets(access_token=access_token)
@@ -240,7 +247,7 @@ def test_update_feature():
         callback=request_callback)
 
     response = Datasets(access_token=access_token).update_feature(
-            'test', '1', {'type': 'Feature'})
+        'test', '1', {'type': 'Feature'})
     assert response.status_code == 200
 
 
diff --git a/tests/test_directions.py b/tests/test_directions.py
index f4160b1..2628d26 100644
--- a/tests/test_directions.py
+++ b/tests/test_directions.py
@@ -21,6 +21,13 @@ points = [{
             36.92217534275667]}}]
 
 
+def test_class_attrs():
+    """Get expected class attr values"""
+    serv = mapbox.Directions()
+    assert serv.api_name == 'directions'
+    assert serv.api_version == 'v4'
+
+
 @responses.activate
 @pytest.mark.parametrize("cache", [None, DictCache()])
 def test_directions(cache):
@@ -41,7 +48,6 @@ def test_directions(cache):
 
 
 @responses.activate
-
 def test_directions_geojson():
     with open('tests/moors.json') as fh:
         body = fh.read()
diff --git a/tests/test_distances.py b/tests/test_distances.py
index 7abacd7..4c4be8b 100644
--- a/tests/test_distances.py
+++ b/tests/test_distances.py
@@ -29,6 +29,13 @@ points = [{
             36.922175]}}]
 
 
+def test_class_attrs():
+    """Get expected class attr values"""
+    serv = mapbox.Distance()
+    assert serv.api_name == 'distances'
+    assert serv.api_version == 'v1'
+
+
 def test_profile_invalid():
     """'jetpack' is not a valid profile."""
     with pytest.raises(ValueError):
@@ -74,21 +81,3 @@ def test_distances_matrix():
     # 3x3 list
     assert len(matrix) == 3
     assert len(matrix[0]) == 3
-
-
-@responses.activate
-def test_distances_matrix():
-
-    responses.add(
-        responses.POST,
-        'https://api.mapbox.com/distances/v1/mapbox/driving?access_token=pk.test',
-        match_querystring=True,
-        body='{"durations":[[0,4977,5951],[4963,0,9349],[5881,9317,0]]}',
-        status=200,
-        content_type='application/json')
-
-    res = mapbox.Distance(access_token='pk.test').distances(points)
-    matrix = res.json()['durations']
-    # 3x3 list
-    assert len(matrix) == 3
-    assert len(matrix[0]) == 3
diff --git a/tests/test_geocoder.py b/tests/test_geocoder.py
index 46efa78..7f17b54 100644
--- a/tests/test_geocoder.py
+++ b/tests/test_geocoder.py
@@ -8,6 +8,13 @@ import pytest
 import mapbox
 
 
+def test_class_attrs():
+    """Get expected class attr values"""
+    serv = mapbox.Geocoder()
+    assert serv.api_name == 'geocoding'
+    assert serv.api_version == 'v5'
+
+
 def test_geocoder_default_name():
     """Default name is set"""
     geocoder = mapbox.Geocoder()
@@ -121,7 +128,7 @@ def test_validate_country_codes_err():
 
 def test_validate_country():
     assert mapbox.Geocoder()._validate_country_codes(
-        ('us', 'br')) ==  {'country': 'us,br'}
+        ('us', 'br')) == {'country': 'us,br'}
 
 
 def test_validate_place_types_err():
@@ -229,7 +236,7 @@ def test_geocoder_forward_bbox():
 
     response = mapbox.Geocoder(
         access_token='pk.test').forward(
-            'washington', bbox=(-78.3284,38.6039,-78.0428,38.7841))
+            'washington', bbox=(-78.3284, 38.6039, -78.0428, 38.7841))
     assert response.status_code == 200
     assert response.json()['query'] == ["washington"]
 
diff --git a/tests/test_mapmatching.py b/tests/test_mapmatching.py
index 0791a88..53743bd 100644
--- a/tests/test_mapmatching.py
+++ b/tests/test_mapmatching.py
@@ -24,6 +24,13 @@ def line_feature():
                 [13.420631289482117, 52.50294888790448]]}}
 
 
+def test_class_attrs():
+    """Get expected class attr values"""
+    serv = mapbox.MapMatcher()
+    assert serv.api_name == 'matching'
+    assert serv.api_version == 'v4'
+
+
 @responses.activate
 def test_matching(line_feature):
 
diff --git a/tests/test_staticmaps.py b/tests/test_staticmaps.py
index cb325bf..6f1c62d 100644
--- a/tests/test_staticmaps.py
+++ b/tests/test_staticmaps.py
@@ -18,6 +18,13 @@ import responses
 import mapbox
 
 
+def test_class_attrs():
+    """Get expected class attr values"""
+    serv = mapbox.Static()
+    assert serv.api_name is None
+    assert serv.api_version == 'v4'
+
+
 @pytest.fixture
 def points():
     points = [
diff --git a/tests/test_staticstyle.py b/tests/test_staticstyle.py
index 6cf9941..33ca666 100644
--- a/tests/test_staticstyle.py
+++ b/tests/test_staticstyle.py
@@ -33,6 +33,13 @@ def points():
                 coordinates=[-61.6, 12.0]))]
 
 
+def test_class_attrs():
+    """Get expected class attr values"""
+    serv = mapbox.StaticStyle()
+    assert serv.api_name == 'styles'
+    assert serv.api_version == 'v1'
+
+
 @responses.activate
 def test_staticmap_lonlatzpitchbearing():
 
diff --git a/tests/test_surface.py b/tests/test_surface.py
index 562f9c7..c85b656 100644
--- a/tests/test_surface.py
+++ b/tests/test_surface.py
@@ -20,6 +20,13 @@ points = [{
         "coordinates": [-112.083965, 36.053845]}}]
 
 
+def test_class_attrs():
+    """Get expected class attr values"""
+    serv = mapbox.Surface()
+    assert serv.api_name == 'surface'
+    assert serv.api_version == 'v4'
+
+
 @responses.activate
 def test_surface():
     body = """{"results":[{"id":0,"latlng":{"lat":36.05322,"lng":-112.084004},"ele":2186.361304424316},{"id":1,"latlng":{"lat":36.053573,"lng":-112.083914},"ele":2187.6233827411997},{"id":2,"latlng":{"lat":36.053845,"lng":-112.083965},"ele":2163.921475128245}],"attribution":"&lt;a href='https://www.mapbox.com/about/maps/' target='_blank'&gt;&amp;copy; Mapbox&lt;/a&gt;"}"""
diff --git a/tests/test_upload.py b/tests/test_upload.py
index 1afcfc3..9b2ec99 100644
--- a/tests/test_upload.py
+++ b/tests/test_upload.py
@@ -25,6 +25,13 @@ upload_response_body = """
     "name": null}}""".format(username=username)
 
 
+def test_class_attrs():
+    """Get expected class attr values"""
+    serv = mapbox.Uploader()
+    assert serv.api_name == 'uploads'
+    assert serv.api_version == 'v1'
+
+
 @responses.activate
 def test_get_credentials():
     query_body = """

pip install -e .[test]
parse_log_pytest
requirements.txt
pytest pytest-cov
3.6
requirements/base.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
attrs==22.2.0
boto3==1.23.10
botocore==1.26.10
CacheControl==0.12.14
certifi==2021.5.30
charset-normalizer==2.0.12
click==8.0.4
click-plugins==1.1.1
cligj==0.7.2
coverage==6.2
coveralls==3.3.1
distlib==0.3.9
docopt==0.6.2
filelock==3.4.1
idna==3.10
importlib-metadata==4.8.3
importlib-resources==5.4.0
iniconfig==1.1.1
iso3166==2.1.1
jmespath==0.10.0
-e git+https://github.com/mapbox/mapbox-sdk-py.git@2a5971f9b4f90ae23bb52ff5f273ce7061b23461#egg=mapbox
msgpack==1.0.5
packaging==21.3
platformdirs==2.4.0
pluggy==1.0.0
polyline==1.4.0
py==1.11.0
pyparsing==3.1.4
pytest==7.0.1
pytest-cov==4.0.0
python-dateutil==2.9.0.post0
requests==2.27.1
responses==0.17.0
s3transfer==0.5.2
six==1.17.0
toml==0.10.2
tomli==1.2.3
tox==3.28.0
typing_extensions==4.1.1
uritemplate==4.1.1
urllib3==1.26.20
virtualenv==20.17.1
zipp==3.6.0

name: mapbox-sdk-py
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2021.5.30=py36h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.3=he6710b0_2
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - pip=21.2.2=py36h06a4308_0
  - python=3.6.13=h12debd9_1
  - readline=8.2=h5eee18b_0
  - setuptools=58.0.4=py36h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.37.1=pyhd3eb1b0_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - attrs==22.2.0
      - boto3==1.23.10
      - botocore==1.26.10
      - cachecontrol==0.12.14
      - charset-normalizer==2.0.12
      - click==8.0.4
      - click-plugins==1.1.1
      - cligj==0.7.2
      - coverage==6.2
      - coveralls==3.3.1
      - distlib==0.3.9
      - docopt==0.6.2
      - filelock==3.4.1
      - idna==3.10
      - importlib-metadata==4.8.3
      - importlib-resources==5.4.0
      - iniconfig==1.1.1
      - iso3166==2.1.1
      - jmespath==0.10.0
      - msgpack==1.0.5
      - packaging==21.3
      - platformdirs==2.4.0
      - pluggy==1.0.0
      - polyline==1.4.0
      - py==1.11.0
      - pyparsing==3.1.4
      - pytest==7.0.1
      - pytest-cov==4.0.0
      - python-dateutil==2.9.0.post0
      - requests==2.27.1
      - responses==0.17.0
      - s3transfer==0.5.2
      - six==1.17.0
      - toml==0.10.2
      - tomli==1.2.3
      - tox==3.28.0
      - typing-extensions==4.1.1
      - uritemplate==4.1.1
      - urllib3==1.26.20
      - virtualenv==20.17.1
      - zipp==3.6.0
prefix: /opt/conda/envs/mapbox-sdk-py

tests/test_analytics.py::test_class_attrs tests/test_base.py::test_class_attrs tests/test_datasets.py::test_class_attrs tests/test_directions.py::test_class_attrs tests/test_distances.py::test_class_attrs tests/test_geocoder.py::test_class_attrs tests/test_mapmatching.py::test_class_attrs tests/test_staticmaps.py::test_class_attrs tests/test_staticstyle.py::test_class_attrs tests/test_surface.py::test_class_attrs tests/test_upload.py::test_class_attrs
tests/test_analytics.py::test_resource_type_invalid tests/test_analytics.py::test_profile_valid[tokens] tests/test_analytics.py::test_profile_valid[styles] tests/test_analytics.py::test_profile_valid[accounts] tests/test_analytics.py::test_profile_valid[tilesets] tests/test_analytics.py::test_period_invalid[2016-03-22T00:00:00.000Z-None] tests/test_analytics.py::test_period_invalid[2016-03-22T00:00:00.000Z-2016-03-20T00:00:00.000Z] tests/test_analytics.py::test_period_invalid[2016-03-22T00:00:00.000Z-2017-04-20T00:00:00.000Z] tests/test_analytics.py::test_period_valid[2016-03-22T00:00:00.000Z-2016-03-24T00:00:00.000Z] tests/test_analytics.py::test_period_valid[None-None] tests/test_analytics.py::test_username_invalid tests/test_analytics.py::test_username_valid tests/test_analytics.py::test_id_invalid tests/test_analytics.py::test_id_valid[accounts-None] tests/test_analytics.py::test_id_valid[tokens-abc] tests/test_analytics.py::test_analytics tests/test_base.py::test_service_session tests/test_base.py::test_service_session_env tests/test_base.py::test_service_session_os_environ tests/test_base.py::test_service_session_os_environ_caps tests/test_base.py::test_service_session_os_environ_precedence tests/test_base.py::test_user_agent tests/test_base.py::test_custom_messages tests/test_base.py::test_username tests/test_base.py::test_default_host tests/test_base.py::test_configured_host tests/test_base.py::test_username_failures tests/test_datasets.py::test_datasets_service_properties tests/test_datasets.py::test_datasets_list tests/test_datasets.py::test_datasets_create tests/test_datasets.py::test_dataset_read tests/test_datasets.py::test_dataset_update tests/test_datasets.py::test_delete_dataset tests/test_datasets.py::test_dataset_list_features tests/test_datasets.py::test_dataset_list_features_reverse tests/test_datasets.py::test_dataset_list_features_pagination tests/test_datasets.py::test_read_feature tests/test_datasets.py::test_update_feature tests/test_datasets.py::test_delete_feature tests/test_directions.py::test_directions[None] tests/test_directions.py::test_directions[cache1] tests/test_directions.py::test_directions_geojson tests/test_directions.py::test_invalid_profile tests/test_directions.py::test_direction_params tests/test_directions.py::test_invalid_geom_encoding tests/test_directions.py::test_invalid_instruction_format tests/test_distances.py::test_profile_invalid tests/test_distances.py::test_profile_valid[driving] tests/test_distances.py::test_profile_valid[cycling] tests/test_distances.py::test_profile_valid[walking] tests/test_distances.py::test_distance tests/test_distances.py::test_distances_matrix tests/test_geocoder.py::test_geocoder_default_name tests/test_geocoder.py::test_geocoder_name tests/test_geocoder.py::test_geocoder_forward tests/test_geocoder.py::test_geocoder_forward_geojson tests/test_geocoder.py::test_geocoder_reverse tests/test_geocoder.py::test_geocoder_reverse_geojson tests/test_geocoder.py::test_geocoder_place_types tests/test_geocoder.py::test_validate_country_codes_err tests/test_geocoder.py::test_validate_country tests/test_geocoder.py::test_validate_place_types_err tests/test_geocoder.py::test_validate_place_types tests/test_geocoder.py::test_geocoder_forward_types tests/test_geocoder.py::test_geocoder_reverse_types tests/test_geocoder.py::test_geocoder_forward_proximity tests/test_geocoder.py::test_geocoder_proximity_rounding tests/test_geocoder.py::test_geocoder_forward_bbox tests/test_geocoder.py::test_geocoder_forward_limit tests/test_geocoder.py::test_geocoder_reverse_limit tests/test_geocoder.py::test_geocoder_reverse_limit_requires_onetype tests/test_geocoder.py::test_geocoder_reverse_rounding tests/test_geocoder.py::test_geocoder_unicode tests/test_geocoder.py::test_geocoder_forward_country tests/test_geocoder.py::test_geocoder_language tests/test_mapmatching.py::test_matching tests/test_mapmatching.py::test_matching_precision tests/test_mapmatching.py::test_invalid_feature tests/test_mapmatching.py::test_invalid_profile tests/test_staticmaps.py::test_staticmap_lonlatz_only tests/test_staticmaps.py::test_staticmap_lonlatz_features tests/test_staticmaps.py::test_staticmap_auto_features tests/test_staticmaps.py::test_staticmap_auto_nofeatures tests/test_staticmaps.py::test_staticmap_featurestoolarge tests/test_staticmaps.py::test_staticmap_imagesize tests/test_staticmaps.py::test_latlon tests/test_staticmaps.py::test_lon_invalid tests/test_staticmaps.py::test_staticmap_retina tests/test_staticstyle.py::test_staticmap_lonlatzpitchbearing tests/test_staticstyle.py::test_staticmap_lonlatz_features tests/test_staticstyle.py::test_staticmap_auto_features tests/test_staticstyle.py::test_staticmap_auto_nofeatures tests/test_staticstyle.py::test_staticmap_featurestoolarge tests/test_staticstyle.py::test_staticmap_validate_bearing tests/test_staticstyle.py::test_staticmap_validate_pitch tests/test_staticstyle.py::test_staticmap_imagesize tests/test_staticstyle.py::test_latlon tests/test_staticstyle.py::test_lon_invalid tests/test_staticstyle.py::test_staticmap_options tests/test_staticstyle.py::test_staticmap_tile tests/test_staticstyle.py::test_bad_tilesize tests/test_staticstyle.py::test_staticmap_tile_retina tests/test_staticstyle.py::test_staticmap_wmts tests/test_staticstyle.py::test_staticmap_retina tests/test_staticstyle.py::test_staticmap_twox_deprecated tests/test_staticstyle.py::test_staticmap_twox_deprecated_error tests/test_surface.py::test_surface tests/test_surface.py::test_surface_geojson tests/test_surface.py::test_surface_params tests/test_upload.py::test_get_credentials tests/test_upload.py::test_create tests/test_upload.py::test_create_name tests/test_upload.py::test_list tests/test_upload.py::test_status tests/test_upload.py::test_delete tests/test_upload.py::test_stage tests/test_upload.py::test_stage_filename tests/test_upload.py::test_big_stage tests/test_upload.py::test_upload tests/test_upload.py::test_upload_error tests/test_upload.py::test_upload_patch tests/test_upload.py::test_upload_tileset_validation tests/test_upload.py::test_upload_tileset_validation_username tests/test_upload.py::test_create_tileset_validation
README.rst mapbox/services/base.py mapbox/services/distance.py mapbox/services/static_style.py mapbox/services/directions.py mapbox/services/surface.py mapbox/services/analytics.py mapbox/services/geocoding.py CHANGES .travis.yml mapbox/services/datasets.py mapbox/services/mapmatching.py mapbox/services/static.py tox.ini mapbox/services/uploads.py
README.rst mapbox/services/base.py mapbox/services/distance.py mapbox/services/static_style.py mapbox/services/directions.py mapbox/services/surface.py mapbox/services/analytics.py mapbox/services/geocoding.py CHANGES .travis.yml mapbox/services/datasets.py mapbox/services/mapmatching.py mapbox/services/static.py tox.ini mapbox/services/uploads.py