Repository: box/box-python-sdk

Issue:
Add Box SDK headers to API calls
We should definitely send headers for SDK name and SDK version. Other nice-to-haves to consider:

- Python version
- Requests version

Discussion:
boxcla: Verified that @mattwiller has signed the CLA. Thanks for the pull request!
coveralls: ## Pull Request Test Coverage Report for [Build 1093](https://coveralls.io/builds/19377329)

* **3** of **3**   **(100.0%)**  changed or added relevant lines in **2** files are covered.
* No unchanged relevant lines lost coverage.
* Overall coverage increased (+**0.005%**) to **94.528%**

---



|  Totals | [![Coverage Status](https://coveralls.io/builds/19377329/badge)](https://coveralls.io/builds/19377329) |
| :-- | --: |
| Change from base [Build 1084](https://coveralls.io/builds/19316485): |  0.005% |
| Covered Lines: | 2073 |
| Relevant Lines: | 2193 |

---
##### 💛  - [Coveralls](https://coveralls.io)


Patch:
diff --git a/boxsdk/config.py b/boxsdk/config.py
index 203cfc2..371117d 100644
--- a/boxsdk/config.py
+++ b/boxsdk/config.py
@@ -2,6 +2,8 @@
 
 from __future__ import unicode_literals, absolute_import
 
+from sys import version_info as py_version
+
 from . import version
 
 
@@ -17,3 +19,9 @@ class Client(object):
     """Configuration object containing the user agent string."""
     VERSION = version.__version__
     USER_AGENT_STRING = 'box-python-sdk-{0}'.format(VERSION)
+    BOX_UA_STRING = 'agent=box-python-sdk/{0}; env=python/{1}.{2}.{3}'.format(
+        VERSION,
+        py_version.major,
+        py_version.minor,
+        py_version.micro,
+    )
diff --git a/boxsdk/session/session.py b/boxsdk/session/session.py
index e9c0b14..d8a41ba 100644
--- a/boxsdk/session/session.py
+++ b/boxsdk/session/session.py
@@ -64,7 +64,10 @@ def __init__(
         self._client_config = client_config or Client()
         super(Session, self).__init__()
         self._network_layer = network_layer or DefaultNetwork()
-        self._default_headers = {'User-Agent': self._client_config.USER_AGENT_STRING}
+        self._default_headers = {
+            'User-Agent': self._client_config.USER_AGENT_STRING,
+            'X-Box-UA': self._client_config.BOX_UA_STRING,
+        }
         self._translator = translator
         self._default_network_request_kwargs = {}
         if default_headers:


Test patch:
diff --git a/test/integration/test_as_user.py b/test/integration/test_as_user.py
index 45cff68..372de7d 100644
--- a/test/integration/test_as_user.py
+++ b/test/integration/test_as_user.py
@@ -14,6 +14,7 @@ def as_user_headers(mock_user_id, access_token):
         'Authorization': 'Bearer {0}'.format(access_token),
         'As-User': mock_user_id,
         'User-Agent': Client.USER_AGENT_STRING,
+        'X-Box-UA': Client.BOX_UA_STRING,
     }
 
 
diff --git a/test/integration/test_retry_and_refresh.py b/test/integration/test_retry_and_refresh.py
index 057ed43..f27858c 100644
--- a/test/integration/test_retry_and_refresh.py
+++ b/test/integration/test_retry_and_refresh.py
@@ -29,7 +29,7 @@ def test_automatic_refresh(
             'POST',
             '{0}/token'.format(API.OAUTH2_API_URL),
             data=ANY,
-            headers={'content-type': 'application/x-www-form-urlencoded', 'User-Agent': ANY},
+            headers={'content-type': 'application/x-www-form-urlencoded', 'User-Agent': ANY, 'X-Box-UA': ANY},
         ),
         call(
             'GET',
diff --git a/test/integration/test_with_shared_link.py b/test/integration/test_with_shared_link.py
index c4a74d9..6d2af45 100644
--- a/test/integration/test_with_shared_link.py
+++ b/test/integration/test_with_shared_link.py
@@ -26,6 +26,7 @@ def box_api_headers(shared_link, shared_link_password, access_token):
         'Authorization': 'Bearer {0}'.format(access_token),
         'BoxApi': box_api_header,
         'User-Agent': Client.USER_AGENT_STRING,
+        'X-Box-UA': Client.BOX_UA_STRING,
     }