Repository: auth0/auth0-python
Pull request #215 (2020-05-07 23:57:04)

Add connect/read timeout option
### Changes

The connect and read timeout can be customized in the `requests` dependency whenever an HTTP method is called. This is a per request setting, not global.

The accepted values are either a `float` to setting both timeout values to the same value, or a `tuple` to decide values separately.

#### Open to suggestions
- [ ] The default timeout value for both attributes on this PR is set to 5 seconds. Should that change?

### References

This PR is built on top of #209 (see first commit) and supersedes it.

Docs on the attribute: http://requests.kennethreitz.org/en/master/user/advanced/#id16

### Testing

Followed the idea on this comment https://github.com/auth0/auth0-python/pull/209#issuecomment-538047260

- [x] This change adds unit test coverage
- [x] This change adds integration test coverage
- [x] This change has been tested on the latest version of the platform/language or why not

### Checklist

- [x] I have read the [Auth0 general contribution guidelines](https://github.com/auth0/open-source-template/blob/master/GENERAL-CONTRIBUTING.md)
- [x] I have read the [Auth0 Code of Conduct](https://github.com/auth0/open-source-template/blob/master/CODE-OF-CONDUCT.md)
- [ ] All existing and new tests complete without errors


adamjmcgrath: lgtm - it's a shame there isn't a global/environmental variable way of setting the timeout in requests

Patch:
diff --git a/auth0/v3/authentication/base.py b/auth0/v3/authentication/base.py
index 8e60ff8..bfb770f 100644
--- a/auth0/v3/authentication/base.py
+++ b/auth0/v3/authentication/base.py
@@ -16,11 +16,15 @@ class AuthenticationBase(object):
     Args:
         telemetry (bool, optional): Enable or disable Telemetry
             (defaults to True)
+        timeout (float or tuple, optional): Change the requests
+            connect and read timeout. Pass a tuple to specify
+            both values separately or a float to set both to it.
+            (defaults to 5.0 for both)
     """
 
-    def __init__(self, domain, telemetry=True):
+    def __init__(self, domain, telemetry=True, timeout=5.0):
         self.domain = domain
-
+        self.timeout = timeout
         self.base_headers = {'Content-Type': 'application/json'}
 
         if telemetry:
@@ -43,13 +47,13 @@ class AuthenticationBase(object):
     def post(self, url, data=None, headers=None):
         request_headers = self.base_headers.copy()
         request_headers.update(headers or {})
-        response = requests.post(url=url, json=data, headers=request_headers)
+        response = requests.post(url=url, json=data, headers=request_headers, timeout=self.timeout)
         return self._process_response(response)
 
     def get(self, url, params=None, headers=None):
         request_headers = self.base_headers.copy()
         request_headers.update(headers or {})
-        response = requests.get(url=url, params=params, headers=request_headers)
+        response = requests.get(url=url, params=params, headers=request_headers, timeout=self.timeout)
         return self._process_response(response)
 
     def _process_response(self, response):
diff --git a/auth0/v3/management/blacklists.py b/auth0/v3/management/blacklists.py
index 534f190..c1fe86b 100644
--- a/auth0/v3/management/blacklists.py
+++ b/auth0/v3/management/blacklists.py
@@ -11,11 +11,16 @@ class Blacklists(object):
 
         telemetry (bool, optional): Enable or disable Telemetry
             (defaults to True)
+
+        timeout (float or tuple, optional): Change the requests
+            connect and read timeout. Pass a tuple to specify
+            both values separately or a float to set both to it.
+            (defaults to 5.0 for both)
     """
 
-    def __init__(self, domain, token, telemetry=True):
+    def __init__(self, domain, token, telemetry=True, timeout=5.0):
         self.url = 'https://{}/api/v2/blacklists/tokens'.format(domain)
-        self.client = RestClient(jwt=token, telemetry=telemetry)
+        self.client = RestClient(jwt=token, telemetry=telemetry, timeout=timeout)
 
     def get(self, aud=None):
         """Retrieves the jti and aud of all tokens in the blacklist.
diff --git a/auth0/v3/management/client_grants.py b/auth0/v3/management/client_grants.py
index 4322256..b64ae82 100644
--- a/auth0/v3/management/client_grants.py
+++ b/auth0/v3/management/client_grants.py
@@ -12,11 +12,16 @@ class ClientGrants(object):
 
         telemetry (bool, optional): Enable or disable Telemetry
             (defaults to True)
+
+        timeout (float or tuple, optional): Change the requests
+            connect and read timeout. Pass a tuple to specify
+            both values separately or a float to set both to it.
+            (defaults to 5.0 for both)
     """
 
-    def __init__(self, domain, token, telemetry=True):
+    def __init__(self, domain, token, telemetry=True, timeout=5.0):
         self.domain = domain
-        self.client = RestClient(jwt=token, telemetry=telemetry)
+        self.client = RestClient(jwt=token, telemetry=telemetry, timeout=timeout)
 
     def _url(self, id=None):
         url = 'https://{}/api/v2/client-grants'.format(self.domain)
diff --git a/auth0/v3/management/clients.py b/auth0/v3/management/clients.py
index c014217..3bedd58 100644
--- a/auth0/v3/management/clients.py
+++ b/auth0/v3/management/clients.py
@@ -12,11 +12,16 @@ class Clients(object):
 
         telemetry (bool, optional): Enable or disable Telemetry
             (defaults to True)
+
+        timeout (float or tuple, optional): Change the requests
+            connect and read timeout. Pass a tuple to specify
+            both values separately or a float to set both to it.
+            (defaults to 5.0 for both)
     """
 
-    def __init__(self, domain, token, telemetry=True):
+    def __init__(self, domain, token, telemetry=True, timeout=5.0):
         self.domain = domain
-        self.client = RestClient(jwt=token, telemetry=telemetry)
+        self.client = RestClient(jwt=token, telemetry=telemetry, timeout=timeout)
 
     def _url(self, id=None):
         url = 'https://{}/api/v2/clients'.format(self.domain)
diff --git a/auth0/v3/management/connections.py b/auth0/v3/management/connections.py
index 2e2db1c..3c372df 100644
--- a/auth0/v3/management/connections.py
+++ b/auth0/v3/management/connections.py
@@ -11,11 +11,16 @@ class Connections(object):
 
         telemetry (bool, optional): Enable or disable Telemetry
             (defaults to True)
+
+        timeout (float or tuple, optional): Change the requests
+            connect and read timeout. Pass a tuple to specify
+            both values separately or a float to set both to it.
+            (defaults to 5.0 for both)
     """
 
-    def __init__(self, domain, token, telemetry=True):
+    def __init__(self, domain, token, telemetry=True, timeout=5.0):
         self.domain = domain
-        self.client = RestClient(jwt=token, telemetry=telemetry)
+        self.client = RestClient(jwt=token, telemetry=telemetry, timeout=timeout)
 
     def _url(self, id=None):
         url = 'https://{}/api/v2/connections'.format(self.domain)
diff --git a/auth0/v3/management/custom_domains.py b/auth0/v3/management/custom_domains.py
index 98e3d45..c31f19d 100644
--- a/auth0/v3/management/custom_domains.py
+++ b/auth0/v3/management/custom_domains.py
@@ -12,11 +12,16 @@ class CustomDomains(object):
 
         telemetry (bool, optional): Enable or disable Telemetry
             (defaults to True)
+
+        timeout (float or tuple, optional): Change the requests
+            connect and read timeout. Pass a tuple to specify
+            both values separately or a float to set both to it.
+            (defaults to 5.0 for both)
     """
 
-    def __init__(self, domain, token, telemetry=True):
+    def __init__(self, domain, token, telemetry=True, timeout=5.0):
         self.domain = domain
-        self.client = RestClient(jwt=token, telemetry=telemetry)
+        self.client = RestClient(jwt=token, telemetry=telemetry, timeout=timeout)
 
     def _url(self, id=None):
         url = 'https://%s/api/v2/custom-domains' % self.domain
diff --git a/auth0/v3/management/device_credentials.py b/auth0/v3/management/device_credentials.py
index 516a70a..6b7b31d 100644
--- a/auth0/v3/management/device_credentials.py
+++ b/auth0/v3/management/device_credentials.py
@@ -12,11 +12,16 @@ class DeviceCredentials(object):
 
         telemetry (bool, optional): Enable or disable Telemetry
             (defaults to True)
+
+        timeout (float or tuple, optional): Change the requests
+            connect and read timeout. Pass a tuple to specify
+            both values separately or a float to set both to it.
+            (defaults to 5.0 for both)
     """
 
-    def __init__(self, domain, token, telemetry=True):
+    def __init__(self, domain, token, telemetry=True, timeout=5.0):
         self.domain = domain
-        self.client = RestClient(jwt=token, telemetry=telemetry)
+        self.client = RestClient(jwt=token, telemetry=telemetry, timeout=timeout)
 
     def _url(self, id=None):
         url = 'https://{}/api/v2/device-credentials'.format(self.domain)
diff --git a/auth0/v3/management/email_templates.py b/auth0/v3/management/email_templates.py
index 365b4d9..dcda2bf 100644
--- a/auth0/v3/management/email_templates.py
+++ b/auth0/v3/management/email_templates.py
@@ -12,11 +12,16 @@ class EmailTemplates(object):
 
         telemetry (bool, optional): Enable or disable Telemetry
             (defaults to True)
+
+        timeout (float or tuple, optional): Change the requests
+            connect and read timeout. Pass a tuple to specify
+            both values separately or a float to set both to it.
+            (defaults to 5.0 for both)
     """
 
-    def __init__(self, domain, token, telemetry=True):
+    def __init__(self, domain, token, telemetry=True, timeout=5.0):
         self.domain = domain
-        self.client = RestClient(jwt=token, telemetry=telemetry)
+        self.client = RestClient(jwt=token, telemetry=telemetry, timeout=timeout)
 
     def _url(self, id=None):
         url = 'https://{}/api/v2/email-templates'.format(self.domain)
diff --git a/auth0/v3/management/emails.py b/auth0/v3/management/emails.py
index e709846..e88f4e7 100644
--- a/auth0/v3/management/emails.py
+++ b/auth0/v3/management/emails.py
@@ -12,11 +12,16 @@ class Emails(object):
 
         telemetry (bool, optional): Enable or disable Telemetry
             (defaults to True)
+
+        timeout (float or tuple, optional): Change the requests
+            connect and read timeout. Pass a tuple to specify
+            both values separately or a float to set both to it.
+            (defaults to 5.0 for both)
     """
 
-    def __init__(self, domain, token, telemetry=True):
+    def __init__(self, domain, token, telemetry=True, timeout=5.0):
         self.domain = domain
-        self.client = RestClient(jwt=token, telemetry=telemetry)
+        self.client = RestClient(jwt=token, telemetry=telemetry, timeout=timeout)
 
     def _url(self, id=None):
         url = 'https://{}/api/v2/emails/provider'.format(self.domain)
diff --git a/auth0/v3/management/grants.py b/auth0/v3/management/grants.py
index da3b332..d80c4f4 100644
--- a/auth0/v3/management/grants.py
+++ b/auth0/v3/management/grants.py
@@ -12,11 +12,16 @@ class Grants(object):
 
         telemetry (bool, optional): Enable or disable Telemetry
             (defaults to True)
+
+        timeout (float or tuple, optional): Change the requests
+            connect and read timeout. Pass a tuple to specify
+            both values separately or a float to set both to it.
+            (defaults to 5.0 for both)
     """
 
-    def __init__(self, domain, token, telemetry=True):
+    def __init__(self, domain, token, telemetry=True, timeout=5.0):
         self.domain = domain
-        self.client = RestClient(jwt=token, telemetry=telemetry)
+        self.client = RestClient(jwt=token, telemetry=telemetry, timeout=timeout)
 
     def _url(self, id=None):
         url = 'https://%s/api/v2/grants' % self.domain
diff --git a/auth0/v3/management/guardian.py b/auth0/v3/management/guardian.py
index e421b4b..ff77a60 100644
--- a/auth0/v3/management/guardian.py
+++ b/auth0/v3/management/guardian.py
@@ -12,11 +12,16 @@ class Guardian(object):
 
         telemetry (bool, optional): Enable or disable Telemetry
             (defaults to True)
+
+        timeout (float or tuple, optional): Change the requests
+            connect and read timeout. Pass a tuple to specify
+            both values separately or a float to set both to it.
+            (defaults to 5.0 for both)
     """
 
-    def __init__(self, domain, token, telemetry=True):
+    def __init__(self, domain, token, telemetry=True, timeout=5.0):
         self.domain = domain
-        self.client = RestClient(jwt=token, telemetry=telemetry)
+        self.client = RestClient(jwt=token, telemetry=telemetry, timeout=timeout)
 
     def _url(self, id=None):
         url = 'https://{}/api/v2/guardian'.format(self.domain)
diff --git a/auth0/v3/management/jobs.py b/auth0/v3/management/jobs.py
index 9d8864b..eeb2dd4 100644
--- a/auth0/v3/management/jobs.py
+++ b/auth0/v3/management/jobs.py
@@ -12,11 +12,16 @@ class Jobs(object):
 
         telemetry (bool, optional): Enable or disable Telemetry
             (defaults to True)
+
+        timeout (float or tuple, optional): Change the requests
+            connect and read timeout. Pass a tuple to specify
+            both values separately or a float to set both to it.
+            (defaults to 5.0 for both)
     """
 
-    def __init__(self, domain, token, telemetry=True):
+    def __init__(self, domain, token, telemetry=True, timeout=5.0):
         self.domain = domain
-        self.client = RestClient(jwt=token, telemetry=telemetry)
+        self.client = RestClient(jwt=token, telemetry=telemetry, timeout=timeout)
 
     def _url(self, path=None):
         url = 'https://{}/api/v2/jobs'.format(self.domain)
diff --git a/auth0/v3/management/logs.py b/auth0/v3/management/logs.py
index d7b7028..854c4ac 100644
--- a/auth0/v3/management/logs.py
+++ b/auth0/v3/management/logs.py
@@ -12,11 +12,16 @@ class Logs(object):
 
         telemetry (bool, optional): Enable or disable Telemetry
             (defaults to True)
+
+        timeout (float or tuple, optional): Change the requests
+            connect and read timeout. Pass a tuple to specify
+            both values separately or a float to set both to it.
+            (defaults to 5.0 for both)
     """
 
-    def __init__(self, domain, token, telemetry=True):
+    def __init__(self, domain, token, telemetry=True, timeout=5.0):
         self.domain = domain
-        self.client = RestClient(jwt=token, telemetry=telemetry)
+        self.client = RestClient(jwt=token, telemetry=telemetry, timeout=timeout)
 
     def _url(self, id=None):
         url = 'https://{}/api/v2/logs'.format(self.domain)
diff --git a/auth0/v3/management/resource_servers.py b/auth0/v3/management/resource_servers.py
index 90a6be7..61115db 100644
--- a/auth0/v3/management/resource_servers.py
+++ b/auth0/v3/management/resource_servers.py
@@ -12,11 +12,16 @@ class ResourceServers(object):
 
         telemetry (bool, optional): Enable or disable Telemetry
             (defaults to True)
+
+        timeout (float or tuple, optional): Change the requests
+            connect and read timeout. Pass a tuple to specify
+            both values separately or a float to set both to it.
+            (defaults to 5.0 for both)
     """
 
-    def __init__(self, domain, token, telemetry=True):
+    def __init__(self, domain, token, telemetry=True, timeout=5.0):
         self.domain = domain
-        self.client = RestClient(jwt=token, telemetry=telemetry)
+        self.client = RestClient(jwt=token, telemetry=telemetry, timeout=timeout)
 
     def _url(self, id=None):
         url = 'https://{}/api/v2/resource-servers'.format(self.domain)
diff --git a/auth0/v3/management/rest.py b/auth0/v3/management/rest.py
index 013a1d6..8e6fd20 100644
--- a/auth0/v3/management/rest.py
+++ b/auth0/v3/management/rest.py
@@ -11,10 +11,19 @@ UNKNOWN_ERROR = 'a0.sdk.internal.unknown'
 
 class RestClient(object):
 
-    """Provides simple methods for handling all RESTful api endpoints. """
-
-    def __init__(self, jwt, telemetry=True):
+    """Provides simple methods for handling all RESTful api endpoints.
+
+    Args:
+        telemetry (bool, optional): Enable or disable Telemetry
+            (defaults to True)
+        timeout (float or tuple, optional): Change the requests
+            connect and read timeout. Pass a tuple to specify
+            both values separately or a float to set both to it.
+            (defaults to 5.0 for both)
+    """
+    def __init__(self, jwt, telemetry=True, timeout=5.0):
         self.jwt = jwt
+        self.timeout = timeout
 
         self.base_headers = {
             'Authorization': 'Bearer {}'.format(self.jwt),
@@ -40,38 +49,38 @@ class RestClient(object):
     def get(self, url, params=None):
         headers = self.base_headers.copy()
 
-        response = requests.get(url, params=params, headers=headers)
+        response = requests.get(url, params=params, headers=headers, timeout=self.timeout)
         return self._process_response(response)
 
     def post(self, url, data=None):
         headers = self.base_headers.copy()
 
-        response = requests.post(url, json=data, headers=headers)
+        response = requests.post(url, json=data, headers=headers, timeout=self.timeout)
         return self._process_response(response)
 
     def file_post(self, url, data=None, files=None):
         headers = self.base_headers.copy()
         headers.pop('Content-Type', None)
 
-        response = requests.post(url, data=data, files=files, headers=headers)
+        response = requests.post(url, data=data, files=files, headers=headers, timeout=self.timeout)
         return self._process_response(response)
 
     def patch(self, url, data=None):
         headers = self.base_headers.copy()
 
-        response = requests.patch(url, json=data, headers=headers)
+        response = requests.patch(url, json=data, headers=headers, timeout=self.timeout)
         return self._process_response(response)
 
     def put(self, url, data=None):
         headers = self.base_headers.copy()
 
-        response = requests.put(url, json=data, headers=headers)
+        response = requests.put(url, json=data, headers=headers, timeout=self.timeout)
         return self._process_response(response)
 
     def delete(self, url, params=None, data=None):
         headers = self.base_headers.copy()
 
-        response = requests.delete(url, headers=headers, params=params or {}, json=data)
+        response = requests.delete(url, headers=headers, params=params or {}, json=data, timeout=self.timeout)
         return self._process_response(response)
 
     def _process_response(self, response):
diff --git a/auth0/v3/management/roles.py b/auth0/v3/management/roles.py
index 0503d8e..31c004e 100644
--- a/auth0/v3/management/roles.py
+++ b/auth0/v3/management/roles.py
@@ -12,11 +12,16 @@ class Roles(object):
 
         telemetry (bool, optional): Enable or disable Telemetry
             (defaults to True)
+
+        timeout (float or tuple, optional): Change the requests
+            connect and read timeout. Pass a tuple to specify
+            both values separately or a float to set both to it.
+            (defaults to 5.0 for both)
     """
 
-    def __init__(self, domain, token, telemetry=True):
+    def __init__(self, domain, token, telemetry=True, timeout=5.0):
         self.domain = domain
-        self.client = RestClient(jwt=token, telemetry=telemetry)
+        self.client = RestClient(jwt=token, telemetry=telemetry, timeout=timeout)
 
     def _url(self, id=None):
         url = 'https://{}/api/v2/roles'.format(self.domain)
diff --git a/auth0/v3/management/rules.py b/auth0/v3/management/rules.py
index 5838a65..1017362 100644
--- a/auth0/v3/management/rules.py
+++ b/auth0/v3/management/rules.py
@@ -12,11 +12,16 @@ class Rules(object):
 
         telemetry (bool, optional): Enable or disable Telemetry
             (defaults to True)
+
+        timeout (float or tuple, optional): Change the requests
+            connect and read timeout. Pass a tuple to specify
+            both values separately or a float to set both to it.
+            (defaults to 5.0 for both)
     """
 
-    def __init__(self, domain, token, telemetry=True):
+    def __init__(self, domain, token, telemetry=True, timeout=5.0):
         self.domain = domain
-        self.client = RestClient(jwt=token, telemetry=telemetry)
+        self.client = RestClient(jwt=token, telemetry=telemetry, timeout=timeout)
 
     def _url(self, id=None):
         url = 'https://{}/api/v2/rules'.format(self.domain)
diff --git a/auth0/v3/management/rules_configs.py b/auth0/v3/management/rules_configs.py
index 686f101..b29cebe 100644
--- a/auth0/v3/management/rules_configs.py
+++ b/auth0/v3/management/rules_configs.py
@@ -12,11 +12,16 @@ class RulesConfigs(object):
 
         telemetry (bool, optional): Enable or disable Telemetry
             (defaults to True)
+
+        timeout (float or tuple, optional): Change the requests
+            connect and read timeout. Pass a tuple to specify
+            both values separately or a float to set both to it.
+            (defaults to 5.0 for both)
     """
 
-    def __init__(self, domain, token, telemetry=True):
+    def __init__(self, domain, token, telemetry=True, timeout=5.0):
         self.domain = domain
-        self.client = RestClient(jwt=token, telemetry=telemetry)
+        self.client = RestClient(jwt=token, telemetry=telemetry, timeout=timeout)
 
     def _url(self, id=None):
         url = 'https://%s/api/v2/rules-configs' % self.domain
diff --git a/auth0/v3/management/stats.py b/auth0/v3/management/stats.py
index a03507d..8c34ad5 100644
--- a/auth0/v3/management/stats.py
+++ b/auth0/v3/management/stats.py
@@ -11,11 +11,16 @@ class Stats(object):
 
         telemetry (bool, optional): Enable or disable Telemetry
             (defaults to True)
+
+        timeout (float or tuple, optional): Change the requests
+            connect and read timeout. Pass a tuple to specify
+            both values separately or a float to set both to it.
+            (defaults to 5.0 for both)
     """
 
-    def __init__(self, domain, token, telemetry=True):
+    def __init__(self, domain, token, telemetry=True, timeout=5.0):
         self.domain = domain
-        self.client = RestClient(jwt=token, telemetry=telemetry)
+        self.client = RestClient(jwt=token, telemetry=telemetry, timeout=timeout)
 
     def _url(self, action):
         return 'https://{}/api/v2/stats/{}'.format(self.domain, action)
diff --git a/auth0/v3/management/tenants.py b/auth0/v3/management/tenants.py
index b1faef7..8b6ba72 100644
--- a/auth0/v3/management/tenants.py
+++ b/auth0/v3/management/tenants.py
@@ -12,11 +12,16 @@ class Tenants(object):
 
         telemetry (bool, optional): Enable or disable Telemetry
             (defaults to True)
+
+        timeout (float or tuple, optional): Change the requests
+            connect and read timeout. Pass a tuple to specify
+            both values separately or a float to set both to it.
+            (defaults to 5.0 for both)
     """
 
-    def __init__(self, domain, token, telemetry=True):
+    def __init__(self, domain, token, telemetry=True, timeout=5.0):
         self.domain = domain
-        self.client = RestClient(jwt=token, telemetry=telemetry)
+        self.client = RestClient(jwt=token, telemetry=telemetry, timeout=timeout)
 
     def _url(self):
         return 'https://{}/api/v2/tenants/settings'.format(self.domain)
diff --git a/auth0/v3/management/tickets.py b/auth0/v3/management/tickets.py
index bffd9f5..7667787 100644
--- a/auth0/v3/management/tickets.py
+++ b/auth0/v3/management/tickets.py
@@ -12,11 +12,16 @@ class Tickets(object):
 
         telemetry (bool, optional): Enable or disable Telemetry
             (defaults to True)
+
+        timeout (float or tuple, optional): Change the requests
+            connect and read timeout. Pass a tuple to specify
+            both values separately or a float to set both to it.
+            (defaults to 5.0 for both)
     """
 
-    def __init__(self, domain, token, telemetry=True):
+    def __init__(self, domain, token, telemetry=True, timeout=5.0):
         self.domain = domain
-        self.client = RestClient(jwt=token, telemetry=telemetry)
+        self.client = RestClient(jwt=token, telemetry=telemetry, timeout=timeout)
 
     def _url(self, action):
         return 'https://{}/api/v2/tickets/{}'.format(self.domain, action)
diff --git a/auth0/v3/management/user_blocks.py b/auth0/v3/management/user_blocks.py
index 82af8e5..e7670a3 100644
--- a/auth0/v3/management/user_blocks.py
+++ b/auth0/v3/management/user_blocks.py
@@ -12,11 +12,16 @@ class UserBlocks(object):
 
         telemetry (bool, optional): Enable or disable Telemetry
             (defaults to True)
+
+        timeout (float or tuple, optional): Change the requests
+            connect and read timeout. Pass a tuple to specify
+            both values separately or a float to set both to it.
+            (defaults to 5.0 for both)
     """
 
-    def __init__(self, domain, token, telemetry=True):
+    def __init__(self, domain, token, telemetry=True, timeout=5.0):
         self.domain = domain
-        self.client = RestClient(jwt=token, telemetry=telemetry)
+        self.client = RestClient(jwt=token, telemetry=telemetry, timeout=timeout)
 
     def _url(self, id=None):
         url = 'https://{}/api/v2/user-blocks'.format(self.domain)
diff --git a/auth0/v3/management/users.py b/auth0/v3/management/users.py
index 79514e0..6bc7830 100644
--- a/auth0/v3/management/users.py
+++ b/auth0/v3/management/users.py
@@ -12,11 +12,16 @@ class Users(object):
 
         telemetry (bool, optional): Enable or disable Telemetry
             (defaults to True)
+
+        timeout (float or tuple, optional): Change the requests
+            connect and read timeout. Pass a tuple to specify
+            both values separately or a float to set both to it.
+            (defaults to 5.0 for both)
     """
 
-    def __init__(self, domain, token, telemetry=True):
+    def __init__(self, domain, token, telemetry=True, timeout=5.0):
         self.domain = domain
-        self.client = RestClient(jwt=token, telemetry=telemetry)
+        self.client = RestClient(jwt=token, telemetry=telemetry, timeout=timeout)
 
     def _url(self, id=None):
         url = 'https://{}/api/v2/users'.format(self.domain)
diff --git a/auth0/v3/management/users_by_email.py b/auth0/v3/management/users_by_email.py
index c9f582e..295ea0b 100644
--- a/auth0/v3/management/users_by_email.py
+++ b/auth0/v3/management/users_by_email.py
@@ -12,11 +12,16 @@ class UsersByEmail(object):
 
         telemetry (bool, optional): Enable or disable Telemetry
             (defaults to True)
+
+        timeout (float or tuple, optional): Change the requests
+            connect and read timeout. Pass a tuple to specify
+            both values separately or a float to set both to it.
+            (defaults to 5.0 for both)
     """
 
-    def __init__(self, domain, token, telemetry=True):
+    def __init__(self, domain, token, telemetry=True, timeout=5.0):
         self.domain = domain
-        self.client = RestClient(jwt=token, telemetry=telemetry)
+        self.client = RestClient(jwt=token, telemetry=telemetry, timeout=timeout)
 
     def _url(self):
         url = 'https://{}/api/v2/users-by-email'.format(self.domain)


Test patch:
diff --git a/auth0/v3/test/authentication/test_base.py b/auth0/v3/test/authentication/test_base.py
index 804c459..b2426a1 100644
--- a/auth0/v3/test/authentication/test_base.py
+++ b/auth0/v3/test/authentication/test_base.py
@@ -1,5 +1,7 @@
 import base64
 import json
+from time import sleep
+
 import mock
 import sys
 import requests
@@ -43,7 +45,7 @@ class TestBase(unittest.TestCase):
 
     @mock.patch('requests.post')
     def test_post(self, mock_post):
-        ab = AuthenticationBase('auth0.com', telemetry=False)
+        ab = AuthenticationBase('auth0.com', telemetry=False, timeout=(10, 2))
 
         mock_post.return_value.status_code = 200
         mock_post.return_value.text = '{"x": "y"}'
@@ -51,7 +53,7 @@ class TestBase(unittest.TestCase):
         data = ab.post('the-url', data={'a': 'b'}, headers={'c': 'd'})
 
         mock_post.assert_called_with(url='the-url', json={'a': 'b'},
-                headers={'c': 'd', 'Content-Type': 'application/json'})
+                headers={'c': 'd', 'Content-Type': 'application/json'}, timeout=(10, 2))
 
         self.assertEqual(data, {'x': 'y'})
         
@@ -66,7 +68,7 @@ class TestBase(unittest.TestCase):
         data = ab.post('the-url')
 
         mock_post.assert_called_with(url='the-url', json=None,
-                headers={'Content-Type': 'application/json'})
+                headers={'Content-Type': 'application/json'}, timeout=5.0)
 
         self.assertEqual(data, {'x': 'y'})
 
@@ -174,7 +176,7 @@ class TestBase(unittest.TestCase):
 
     @mock.patch('requests.get')
     def test_get(self, mock_get):
-        ab = AuthenticationBase('auth0.com', telemetry=False)
+        ab = AuthenticationBase('auth0.com', telemetry=False, timeout=(10, 2))
 
         mock_get.return_value.status_code = 200
         mock_get.return_value.text = '{"x": "y"}'
@@ -182,7 +184,7 @@ class TestBase(unittest.TestCase):
         data = ab.get('the-url', params={'a': 'b'}, headers={'c': 'd'})
 
         mock_get.assert_called_with(url='the-url', params={'a': 'b'},
-                headers={'c': 'd', 'Content-Type': 'application/json'})
+                headers={'c': 'd', 'Content-Type': 'application/json'}, timeout=(10, 2))
 
         self.assertEqual(data, {'x': 'y'})
 
@@ -197,7 +199,7 @@ class TestBase(unittest.TestCase):
         data = ab.get('the-url')
 
         mock_get.assert_called_with(url='the-url', params=None,
-                headers={'Content-Type': 'application/json'})
+                headers={'Content-Type': 'application/json'}, timeout=5.0)
 
         self.assertEqual(data, {'x': 'y'})
 
@@ -221,3 +223,15 @@ class TestBase(unittest.TestCase):
         self.assertIn('Auth0-Client', headers)
 
         self.assertEqual(data, {"x": "y"})
+
+    def test_get_can_timeout(self):
+        ab = AuthenticationBase('auth0.com', timeout=0.00001)
+
+        with self.assertRaises(requests.exceptions.Timeout):
+            ab.get('https://google.com', params={'a': 'b'}, headers={'c': 'd'})
+
+    def test_post_can_timeout(self):
+        ab = AuthenticationBase('auth0.com', timeout=0.00001)
+
+        with self.assertRaises(requests.exceptions.Timeout):
+            ab.post('https://google.com', data={'a': 'b'}, headers={'c': 'd'})
diff --git a/auth0/v3/test/management/test_blacklists.py b/auth0/v3/test/management/test_blacklists.py
index 27065af..cbf74e9 100644
--- a/auth0/v3/test/management/test_blacklists.py
+++ b/auth0/v3/test/management/test_blacklists.py
@@ -5,6 +5,12 @@ from ...management.blacklists import Blacklists
 
 class TestBlacklists(unittest.TestCase):
 
+    def test_init_with_optionals(self):
+        t = Blacklists(domain='domain', token='jwttoken', telemetry=False, timeout=(10, 2))
+        self.assertEqual(t.client.timeout, (10, 2))
+        telemetry_header = t.client.base_headers.get('Auth0-Client', None)
+        self.assertEqual(telemetry_header, None)
+
     @mock.patch('auth0.v3.management.blacklists.RestClient')
     def test_get(self, mock_rc):
         mock_instance = mock_rc.return_value
diff --git a/auth0/v3/test/management/test_client_grants.py b/auth0/v3/test/management/test_client_grants.py
index 1155649..399c5cb 100644
--- a/auth0/v3/test/management/test_client_grants.py
+++ b/auth0/v3/test/management/test_client_grants.py
@@ -5,6 +5,12 @@ from ...management.client_grants import ClientGrants
 
 class TestClientGrants(unittest.TestCase):
 
+    def test_init_with_optionals(self):
+        t = ClientGrants(domain='domain', token='jwttoken', telemetry=False, timeout=(10, 2))
+        self.assertEqual(t.client.timeout, (10, 2))
+        telemetry_header = t.client.base_headers.get('Auth0-Client', None)
+        self.assertEqual(telemetry_header, None)
+
     @mock.patch('auth0.v3.management.client_grants.RestClient')
     def test_all(self, mock_rc):
         mock_instance = mock_rc.return_value
diff --git a/auth0/v3/test/management/test_clients.py b/auth0/v3/test/management/test_clients.py
index 4e4c10e..58be544 100644
--- a/auth0/v3/test/management/test_clients.py
+++ b/auth0/v3/test/management/test_clients.py
@@ -5,6 +5,12 @@ from ...management.clients import Clients
 
 class TestClients(unittest.TestCase):
 
+    def test_init_with_optionals(self):
+        t = Clients(domain='domain', token='jwttoken', telemetry=False, timeout=(10, 2))
+        self.assertEqual(t.client.timeout, (10, 2))
+        telemetry_header = t.client.base_headers.get('Auth0-Client', None)
+        self.assertEqual(telemetry_header, None)
+
     @mock.patch('auth0.v3.management.clients.RestClient')
     def test_all(self, mock_rc):
         mock_instance = mock_rc.return_value
diff --git a/auth0/v3/test/management/test_connections.py b/auth0/v3/test/management/test_connections.py
index 87a5f50..841f7e8 100644
--- a/auth0/v3/test/management/test_connections.py
+++ b/auth0/v3/test/management/test_connections.py
@@ -5,6 +5,12 @@ from ...management.connections import Connections
 
 class TestConnection(unittest.TestCase):
 
+    def test_init_with_optionals(self):
+        t = Connections(domain='domain', token='jwttoken', telemetry=False, timeout=(10, 2))
+        self.assertEqual(t.client.timeout, (10, 2))
+        telemetry_header = t.client.base_headers.get('Auth0-Client', None)
+        self.assertEqual(telemetry_header, None)
+
     @mock.patch('auth0.v3.management.connections.RestClient')
     def test_all(self, mock_rc):
         mock_instance = mock_rc.return_value
diff --git a/auth0/v3/test/management/test_custom_domains.py b/auth0/v3/test/management/test_custom_domains.py
index d80dc82..2a42dbb 100644
--- a/auth0/v3/test/management/test_custom_domains.py
+++ b/auth0/v3/test/management/test_custom_domains.py
@@ -5,6 +5,12 @@ from ...management.custom_domains import CustomDomains
 
 class TestCustomDomains(unittest.TestCase):
 
+    def test_init_with_optionals(self):
+        t = CustomDomains(domain='domain', token='jwttoken', telemetry=False, timeout=(10, 2))
+        self.assertEqual(t.client.timeout, (10, 2))
+        telemetry_header = t.client.base_headers.get('Auth0-Client', None)
+        self.assertEqual(telemetry_header, None)
+
     @mock.patch('auth0.v3.management.custom_domains.RestClient')
     def test_get_all(self, mock_rc):
         mock_instance = mock_rc.return_value
diff --git a/auth0/v3/test/management/test_device_credentials.py b/auth0/v3/test/management/test_device_credentials.py
index a976f34..c720ba6 100644
--- a/auth0/v3/test/management/test_device_credentials.py
+++ b/auth0/v3/test/management/test_device_credentials.py
@@ -5,6 +5,12 @@ from ...management.device_credentials import DeviceCredentials
 
 class TestDeviceCredentials(unittest.TestCase):
 
+    def test_init_with_optionals(self):
+        t = DeviceCredentials(domain='domain', token='jwttoken', telemetry=False, timeout=(10, 2))
+        self.assertEqual(t.client.timeout, (10, 2))
+        telemetry_header = t.client.base_headers.get('Auth0-Client', None)
+        self.assertEqual(telemetry_header, None)
+
     @mock.patch('auth0.v3.management.device_credentials.RestClient')
     def test_get(self, mock_rc):
         mock_instance = mock_rc.return_value
diff --git a/auth0/v3/test/management/test_email_endpoints.py b/auth0/v3/test/management/test_email_endpoints.py
index d494c37..5ebd190 100644
--- a/auth0/v3/test/management/test_email_endpoints.py
+++ b/auth0/v3/test/management/test_email_endpoints.py
@@ -5,6 +5,12 @@ from ...management.email_templates import EmailTemplates
 
 class TestClients(unittest.TestCase):
 
+    def test_init_with_optionals(self):
+        t = EmailTemplates(domain='domain', token='jwttoken', telemetry=False, timeout=(10, 2))
+        self.assertEqual(t.client.timeout, (10, 2))
+        telemetry_header = t.client.base_headers.get('Auth0-Client', None)
+        self.assertEqual(telemetry_header, None)
+
     @mock.patch('auth0.v3.management.email_templates.RestClient')
     def test_create(self, mock_rc):
         mock_instance = mock_rc.return_value
diff --git a/auth0/v3/test/management/test_emails.py b/auth0/v3/test/management/test_emails.py
index e0a13c5..e212c67 100644
--- a/auth0/v3/test/management/test_emails.py
+++ b/auth0/v3/test/management/test_emails.py
@@ -5,6 +5,12 @@ from ...management.emails import Emails
 
 class TestEmails(unittest.TestCase):
 
+    def test_init_with_optionals(self):
+        t = Emails(domain='domain', token='jwttoken', telemetry=False, timeout=(10, 2))
+        self.assertEqual(t.client.timeout, (10, 2))
+        telemetry_header = t.client.base_headers.get('Auth0-Client', None)
+        self.assertEqual(telemetry_header, None)
+
     @mock.patch('auth0.v3.management.emails.RestClient')
     def test_get(self, mock_rc):
         mock_instance = mock_rc.return_value
diff --git a/auth0/v3/test/management/test_grants.py b/auth0/v3/test/management/test_grants.py
index 35d0636..a9325c0 100644
--- a/auth0/v3/test/management/test_grants.py
+++ b/auth0/v3/test/management/test_grants.py
@@ -5,6 +5,12 @@ from ...management.grants import Grants
 
 class TestGrants(unittest.TestCase):
 
+    def test_init_with_optionals(self):
+        t = Grants(domain='domain', token='jwttoken', telemetry=False, timeout=(10, 2))
+        self.assertEqual(t.client.timeout, (10, 2))
+        telemetry_header = t.client.base_headers.get('Auth0-Client', None)
+        self.assertEqual(telemetry_header, None)
+
     @mock.patch('auth0.v3.management.grants.RestClient')
     def test_get_all(self, mock_rc):
         mock_instance = mock_rc.return_value
diff --git a/auth0/v3/test/management/test_guardian.py b/auth0/v3/test/management/test_guardian.py
index 002e173..3c7b299 100644
--- a/auth0/v3/test/management/test_guardian.py
+++ b/auth0/v3/test/management/test_guardian.py
@@ -5,6 +5,12 @@ from ...management.guardian import Guardian
 
 class TestGuardian(unittest.TestCase):
 
+    def test_init_with_optionals(self):
+        t = Guardian(domain='domain', token='jwttoken', telemetry=False, timeout=(10, 2))
+        self.assertEqual(t.client.timeout, (10, 2))
+        telemetry_header = t.client.base_headers.get('Auth0-Client', None)
+        self.assertEqual(telemetry_header, None)
+
     @mock.patch('auth0.v3.management.guardian.RestClient')
     def test_all_factors(self, mock_rc):
         mock_instance = mock_rc.return_value
diff --git a/auth0/v3/test/management/test_jobs.py b/auth0/v3/test/management/test_jobs.py
index e2685c4..ad49ddf 100644
--- a/auth0/v3/test/management/test_jobs.py
+++ b/auth0/v3/test/management/test_jobs.py
@@ -5,6 +5,12 @@ from ...management.jobs import Jobs
 
 class TestJobs(unittest.TestCase):
 
+    def test_init_with_optionals(self):
+        t = Jobs(domain='domain', token='jwttoken', telemetry=False, timeout=(10, 2))
+        self.assertEqual(t.client.timeout, (10, 2))
+        telemetry_header = t.client.base_headers.get('Auth0-Client', None)
+        self.assertEqual(telemetry_header, None)
+
     @mock.patch('auth0.v3.management.jobs.RestClient')
     def test_get(self, mock_rc):
         mock_instance = mock_rc.return_value
diff --git a/auth0/v3/test/management/test_logs.py b/auth0/v3/test/management/test_logs.py
index 4fa2da6..3075921 100644
--- a/auth0/v3/test/management/test_logs.py
+++ b/auth0/v3/test/management/test_logs.py
@@ -5,6 +5,12 @@ from ...management.logs import Logs
 
 class TestLogs(unittest.TestCase):
 
+    def test_init_with_optionals(self):
+        t = Logs(domain='domain', token='jwttoken', telemetry=False, timeout=(10, 2))
+        self.assertEqual(t.client.timeout, (10, 2))
+        telemetry_header = t.client.base_headers.get('Auth0-Client', None)
+        self.assertEqual(telemetry_header, None)
+
     @mock.patch('auth0.v3.management.logs.RestClient')
     def test_search(self, mock_rc):
         mock_instance = mock_rc.return_value
diff --git a/auth0/v3/test/management/test_resource_servers.py b/auth0/v3/test/management/test_resource_servers.py
index bd1f57f..340bfc4 100644
--- a/auth0/v3/test/management/test_resource_servers.py
+++ b/auth0/v3/test/management/test_resource_servers.py
@@ -5,6 +5,12 @@ from ...management.resource_servers import ResourceServers
 
 class TestResourceServers(unittest.TestCase):
 
+    def test_init_with_optionals(self):
+        t = ResourceServers(domain='domain', token='jwttoken', telemetry=False, timeout=(10, 2))
+        self.assertEqual(t.client.timeout, (10, 2))
+        telemetry_header = t.client.base_headers.get('Auth0-Client', None)
+        self.assertEqual(telemetry_header, None)
+
     @mock.patch('auth0.v3.management.resource_servers.RestClient')
     def test_create(self, mock_rc):
         mock_instance = mock_rc.return_value
diff --git a/auth0/v3/test/management/test_rest.py b/auth0/v3/test/management/test_rest.py
index 5a77317..4d3ac5b 100644
--- a/auth0/v3/test/management/test_rest.py
+++ b/auth0/v3/test/management/test_rest.py
@@ -2,14 +2,111 @@ import unittest
 import sys
 import json
 import base64
-import requests
+
 import mock
+import requests
+
 from ...management.rest import RestClient
 from ...exceptions import Auth0Error
 
 
 class TestRest(unittest.TestCase):
 
+    def test_get_can_timeout(self):
+        rc = RestClient(jwt='a-token', telemetry=False, timeout=0.00001)
+
+        with self.assertRaises(requests.exceptions.Timeout):
+            rc.get('http://google.com')
+
+    def test_post_can_timeout(self):
+        rc = RestClient(jwt='a-token', telemetry=False, timeout=0.00001)
+
+        with self.assertRaises(requests.exceptions.Timeout):
+            rc.post('http://google.com')
+
+    def test_put_can_timeout(self):
+        rc = RestClient(jwt='a-token', telemetry=False, timeout=0.00001)
+
+        with self.assertRaises(requests.exceptions.Timeout):
+            rc.put('http://google.com')
+
+    def test_patch_can_timeout(self):
+        rc = RestClient(jwt='a-token', telemetry=False, timeout=0.00001)
+
+        with self.assertRaises(requests.exceptions.Timeout):
+            rc.patch('http://google.com')
+
+    def test_delete_can_timeout(self):
+        rc = RestClient(jwt='a-token', telemetry=False, timeout=0.00001)
+
+        with self.assertRaises(requests.exceptions.Timeout):
+            rc.delete('http://google.com')
+
+    @mock.patch('requests.get')
+    def test_get_custom_timeout(self, mock_get):
+        rc = RestClient(jwt='a-token', telemetry=False, timeout=(10, 2))
+        headers = {
+            'Authorization': 'Bearer a-token',
+            'Content-Type': 'application/json',
+        }
+        mock_get.return_value.text = '["a", "b"]'
+        mock_get.return_value.status_code = 200
+
+        rc.get('the-url')
+        mock_get.assert_called_with('the-url', params=None, headers=headers, timeout=(10, 2))
+
+    @mock.patch('requests.post')
+    def test_post_custom_timeout(self, mock_post):
+        rc = RestClient(jwt='a-token', telemetry=False, timeout=(10, 2))
+        headers = {
+            'Authorization': 'Bearer a-token',
+            'Content-Type': 'application/json',
+        }
+        mock_post.return_value.text = '["a", "b"]'
+        mock_post.return_value.status_code = 200
+
+        rc.post('the-url')
+        mock_post.assert_called_with('the-url', json=None, headers=headers, timeout=(10, 2))
+
+    @mock.patch('requests.put')
+    def test_put_custom_timeout(self, mock_put):
+        rc = RestClient(jwt='a-token', telemetry=False, timeout=(10, 2))
+        headers = {
+            'Authorization': 'Bearer a-token',
+            'Content-Type': 'application/json',
+        }
+        mock_put.return_value.text = '["a", "b"]'
+        mock_put.return_value.status_code = 200
+
+        rc.put('the-url')
+        mock_put.assert_called_with('the-url', json=None, headers=headers, timeout=(10, 2))
+
+    @mock.patch('requests.patch')
+    def test_patch_custom_timeout(self, mock_patch):
+        rc = RestClient(jwt='a-token', telemetry=False, timeout=(10, 2))
+        headers = {
+            'Authorization': 'Bearer a-token',
+            'Content-Type': 'application/json',
+        }
+        mock_patch.return_value.text = '["a", "b"]'
+        mock_patch.return_value.status_code = 200
+
+        rc.patch('the-url')
+        mock_patch.assert_called_with('the-url', json=None, headers=headers, timeout=(10, 2))
+
+    @mock.patch('requests.delete')
+    def test_delete_custom_timeout(self, mock_delete):
+        rc = RestClient(jwt='a-token', telemetry=False, timeout=(10, 2))
+        headers = {
+            'Authorization': 'Bearer a-token',
+            'Content-Type': 'application/json',
+        }
+        mock_delete.return_value.text = '["a", "b"]'
+        mock_delete.return_value.status_code = 200
+
+        rc.delete('the-url')
+        mock_delete.assert_called_with('the-url', params={}, json=None, headers=headers, timeout=(10, 2))
+
     @mock.patch('requests.get')
     def test_get(self, mock_get):
         rc = RestClient(jwt='a-token', telemetry=False)
@@ -22,14 +119,14 @@ class TestRest(unittest.TestCase):
         mock_get.return_value.status_code = 200
 
         response = rc.get('the-url')
-        mock_get.assert_called_with('the-url', params=None, headers=headers)
+        mock_get.assert_called_with('the-url', params=None, headers=headers, timeout=5.0)
 
         self.assertEqual(response, ['a', 'b'])
 
         response = rc.get(url='the/url', params={'A': 'param', 'B': 'param'})
         mock_get.assert_called_with('the/url', params={'A': 'param',
                                                        'B': 'param'},
-                                    headers=headers)
+                                    headers=headers, timeout=5.0)
         self.assertEqual(response, ['a', 'b'])
 
         mock_get.return_value.text = ''
@@ -65,7 +162,7 @@ class TestRest(unittest.TestCase):
         mock_post.return_value.status_code = 200
         response = rc.post('the/url', data=data)
         mock_post.assert_called_with('the/url', json=data,
-                                     headers=headers)
+                                     headers=headers, timeout=5.0)
 
         self.assertEqual(response, {'a': 'b'})
 
@@ -213,7 +310,7 @@ class TestRest(unittest.TestCase):
 
         rc.file_post('the-url', data=data, files=files)
 
-        mock_post.assert_called_once_with('the-url', data=data, files=files, headers=headers)
+        mock_post.assert_called_once_with('the-url', data=data, files=files, headers=headers, timeout=5.0)
 
 
     @mock.patch('requests.put')
@@ -229,7 +326,7 @@ class TestRest(unittest.TestCase):
 
         response = rc.put(url='the-url', data=data)
         mock_put.assert_called_with('the-url', json=data,
-                                      headers=headers)
+                                      headers=headers, timeout=5.0)
 
         self.assertEqual(response, ['a', 'b'])
 
@@ -262,7 +359,7 @@ class TestRest(unittest.TestCase):
 
         response = rc.patch(url='the-url', data=data)
         mock_patch.assert_called_with('the-url', json=data,
-                                      headers=headers)
+                                      headers=headers, timeout=5.0)
 
         self.assertEqual(response, ['a', 'b'])
 
@@ -294,7 +391,7 @@ class TestRest(unittest.TestCase):
         mock_delete.return_value.status_code = 200
 
         response = rc.delete(url='the-url/ID')
-        mock_delete.assert_called_with('the-url/ID', headers=headers, params={}, json=None)
+        mock_delete.assert_called_with('the-url/ID', headers=headers, params={}, json=None, timeout=5.0)
 
         self.assertEqual(response, ['a', 'b'])
 
@@ -313,7 +410,7 @@ class TestRest(unittest.TestCase):
         params={'A': 'param', 'B': 'param'}
 
         response = rc.delete(url='the-url/ID', params=params, data=data)
-        mock_delete.assert_called_with('the-url/ID', headers=headers, params=params, json=data)
+        mock_delete.assert_called_with('the-url/ID', headers=headers, params=params, json=data, timeout=5.0)
 
         self.assertEqual(response, ['a', 'b'])
 
diff --git a/auth0/v3/test/management/test_roles.py b/auth0/v3/test/management/test_roles.py
index 76ccec1..2742a08 100644
--- a/auth0/v3/test/management/test_roles.py
+++ b/auth0/v3/test/management/test_roles.py
@@ -5,6 +5,12 @@ from ...management.roles import Roles
 
 class TestRoles(unittest.TestCase):
 
+    def test_init_with_optionals(self):
+        t = Roles(domain='domain', token='jwttoken', telemetry=False, timeout=(10, 2))
+        self.assertEqual(t.client.timeout, (10, 2))
+        telemetry_header = t.client.base_headers.get('Auth0-Client', None)
+        self.assertEqual(telemetry_header, None)
+
     @mock.patch('auth0.v3.management.roles.RestClient')
     def test_list(self, mock_rc):
         mock_instance = mock_rc.return_value
diff --git a/auth0/v3/test/management/test_rules.py b/auth0/v3/test/management/test_rules.py
index d57da95..2db7813 100644
--- a/auth0/v3/test/management/test_rules.py
+++ b/auth0/v3/test/management/test_rules.py
@@ -5,6 +5,12 @@ from ...management.rules import Rules
 
 class TestRules(unittest.TestCase):
 
+    def test_init_with_optionals(self):
+        t = Rules(domain='domain', token='jwttoken', telemetry=False, timeout=(10, 2))
+        self.assertEqual(t.client.timeout, (10, 2))
+        telemetry_header = t.client.base_headers.get('Auth0-Client', None)
+        self.assertEqual(telemetry_header, None)
+
     @mock.patch('auth0.v3.management.rules.RestClient')
     def test_all(self, mock_rc):
         mock_instance = mock_rc.return_value
diff --git a/auth0/v3/test/management/test_rules_configs.py b/auth0/v3/test/management/test_rules_configs.py
index d3c41e5..9e6babf 100644
--- a/auth0/v3/test/management/test_rules_configs.py
+++ b/auth0/v3/test/management/test_rules_configs.py
@@ -3,7 +3,13 @@ import mock
 from ...management.rules_configs import RulesConfigs
 
 
-class TestRules(unittest.TestCase):
+class TestRulesConfigs(unittest.TestCase):
+
+    def test_init_with_optionals(self):
+        t = RulesConfigs(domain='domain', token='jwttoken', telemetry=False, timeout=(10, 2))
+        self.assertEqual(t.client.timeout, (10, 2))
+        telemetry_header = t.client.base_headers.get('Auth0-Client', None)
+        self.assertEqual(telemetry_header, None)
 
     @mock.patch('auth0.v3.management.rules_configs.RestClient')
     def test_all(self, mock_rc):
diff --git a/auth0/v3/test/management/test_stats.py b/auth0/v3/test/management/test_stats.py
index d7db82e..91f9461 100644
--- a/auth0/v3/test/management/test_stats.py
+++ b/auth0/v3/test/management/test_stats.py
@@ -3,7 +3,13 @@ import mock
 from ...management.stats import Stats
 
 
-class TestTickets(unittest.TestCase):
+class TestStats(unittest.TestCase):
+
+    def test_init_with_optionals(self):
+        t = Stats(domain='domain', token='jwttoken', telemetry=False, timeout=(10, 2))
+        self.assertEqual(t.client.timeout, (10, 2))
+        telemetry_header = t.client.base_headers.get('Auth0-Client', None)
+        self.assertEqual(telemetry_header, None)
 
     @mock.patch('auth0.v3.management.stats.RestClient')
     def test_active_users(self, mock_rc):
diff --git a/auth0/v3/test/management/test_tenants.py b/auth0/v3/test/management/test_tenants.py
index 37ac552..0838c05 100644
--- a/auth0/v3/test/management/test_tenants.py
+++ b/auth0/v3/test/management/test_tenants.py
@@ -5,6 +5,12 @@ from ...management.tenants import Tenants
 
 class TestTenants(unittest.TestCase):
 
+    def test_init_with_optionals(self):
+        t = Tenants(domain='domain', token='jwttoken', telemetry=False, timeout=(10, 2))
+        self.assertEqual(t.client.timeout, (10, 2))
+        telemetry_header = t.client.base_headers.get('Auth0-Client', None)
+        self.assertEqual(telemetry_header, None)
+
     @mock.patch('auth0.v3.management.tenants.RestClient')
     def test_get(self, mock_rc):
         mock_instance = mock_rc.return_value
diff --git a/auth0/v3/test/management/test_tickets.py b/auth0/v3/test/management/test_tickets.py
index eb0b75f..3bbd2e5 100644
--- a/auth0/v3/test/management/test_tickets.py
+++ b/auth0/v3/test/management/test_tickets.py
@@ -5,6 +5,12 @@ from ...management.tickets import Tickets
 
 class TestTickets(unittest.TestCase):
 
+    def test_init_with_optionals(self):
+        t = Tickets(domain='domain', token='jwttoken', telemetry=False, timeout=(10, 2))
+        self.assertEqual(t.client.timeout, (10, 2))
+        telemetry_header = t.client.base_headers.get('Auth0-Client', None)
+        self.assertEqual(telemetry_header, None)
+
     @mock.patch('auth0.v3.management.tickets.RestClient')
     def test_email(self, mock_rc):
         mock_instance = mock_rc.return_value
diff --git a/auth0/v3/test/management/test_user_blocks.py b/auth0/v3/test/management/test_user_blocks.py
index ec096d5..c240c04 100644
--- a/auth0/v3/test/management/test_user_blocks.py
+++ b/auth0/v3/test/management/test_user_blocks.py
@@ -5,6 +5,12 @@ from ...management.user_blocks import UserBlocks
 
 class TestUserBlocks(unittest.TestCase):
 
+    def test_init_with_optionals(self):
+        t = UserBlocks(domain='domain', token='jwttoken', telemetry=False, timeout=(10, 2))
+        self.assertEqual(t.client.timeout, (10, 2))
+        telemetry_header = t.client.base_headers.get('Auth0-Client', None)
+        self.assertEqual(telemetry_header, None)
+
     @mock.patch('auth0.v3.management.user_blocks.RestClient')
     def test_get_by_identifier(self, mock_rc):
         mock_instance = mock_rc.return_value
diff --git a/auth0/v3/test/management/test_users.py b/auth0/v3/test/management/test_users.py
index b3908c1..fc9bc10 100644
--- a/auth0/v3/test/management/test_users.py
+++ b/auth0/v3/test/management/test_users.py
@@ -5,6 +5,12 @@ from ...management.users import Users
 
 class TestUsers(unittest.TestCase):
 
+    def test_init_with_optionals(self):
+        t = Users(domain='domain', token='jwttoken', telemetry=False, timeout=(10, 2))
+        self.assertEqual(t.client.timeout, (10, 2))
+        telemetry_header = t.client.base_headers.get('Auth0-Client', None)
+        self.assertEqual(telemetry_header, None)
+
     @mock.patch('auth0.v3.management.users.RestClient')
     def test_list(self, mock_rc):
         mock_instance = mock_rc.return_value
diff --git a/auth0/v3/test/management/test_users_by_email.py b/auth0/v3/test/management/test_users_by_email.py
index 2c6e9af..3d947f0 100644
--- a/auth0/v3/test/management/test_users_by_email.py
+++ b/auth0/v3/test/management/test_users_by_email.py
@@ -5,6 +5,12 @@ from ...management.users_by_email import UsersByEmail
 
 class TestUsersByEmail(unittest.TestCase):
 
+    def test_init_with_optionals(self):
+        t = UsersByEmail(domain='domain', token='jwttoken', telemetry=False, timeout=(10, 2))
+        self.assertEqual(t.client.timeout, (10, 2))
+        telemetry_header = t.client.base_headers.get('Auth0-Client', None)
+        self.assertEqual(telemetry_header, None)
+
     @mock.patch('auth0.v3.management.users_by_email.RestClient')
     def test_search_users_by_email(self, mock_rc):
         mock_instance = mock_rc.return_value