diff options
author | Sybren A. Stüvel <sybren@stuvel.eu> | 2019-05-16 13:39:29 +0300 |
---|---|---|
committer | Sybren A. Stüvel <sybren@stuvel.eu> | 2019-05-16 13:39:29 +0300 |
commit | 2e5b7a4a044ab982af66def583ae16bb563a1357 (patch) | |
tree | a09438ba3245519c6b7a49342c3527bb1baee5e0 /blender_id | |
parent | e5c3ae31189b3acb54d33061da2bd27c3d0abad5 (diff) |
Updated Blender ID add-on from upstream
Includes:
- 069540e (2019-05-16) Bumped version to 1.9.99
- cf48253 (2019-05-16) Include Blender and add-on version in User-Agent header
- 4b3d527 (2019-05-16) Automatically retry failed connections to Blender ID for more stability
Diffstat (limited to 'blender_id')
-rw-r--r-- | blender_id/CHANGELOG.md | 2 | ||||
-rw-r--r-- | blender_id/__init__.py | 2 | ||||
-rw-r--r-- | blender_id/communication.py | 77 |
3 files changed, 61 insertions, 20 deletions
diff --git a/blender_id/CHANGELOG.md b/blender_id/CHANGELOG.md index ee36a7fe..cb0c1868 100644 --- a/blender_id/CHANGELOG.md +++ b/blender_id/CHANGELOG.md @@ -8,6 +8,8 @@ - Log which Blender ID instance is communicated with. - Show which Blender ID instance is communicated with in the addon preferences, if it was overridden by setting the BLENDER_ID_ENDPOINT environment variable. +- Automatically retry failed connections to Blender ID for more stability. +- Include Blender and add-on version in User-Agent header when communicating with Blender ID. # Version 1.5 (released 2018-07-03) diff --git a/blender_id/__init__.py b/blender_id/__init__.py index 496c867d..42d7df02 100644 --- a/blender_id/__init__.py +++ b/blender_id/__init__.py @@ -23,7 +23,7 @@ bl_info = { 'name': 'Blender ID authentication', 'author': 'Sybren A. Stüvel, Francesco Siddi, and Inês Almeida', - 'version': (1, 9, 9), + 'version': (1, 9, 99), 'blender': (2, 80, 0), 'location': 'Add-on preferences', 'description': diff --git a/blender_id/communication.py b/blender_id/communication.py index 65fdf4cf..72bf90fe 100644 --- a/blender_id/communication.py +++ b/blender_id/communication.py @@ -27,6 +27,9 @@ log = logging.getLogger(__name__) # Can be overridden by setting the environment variable BLENDER_ID_ENDPOINT. BLENDER_ID_ENDPOINT = 'https://www.blender.org/id/' +# Will become a requests.Session at the first request to Blender ID. +requests_session = None + class BlenderIdCommError(RuntimeError): """Raised when there was an error communicating with Blender ID""" @@ -50,6 +53,41 @@ def host_label(): return 'Blender running on %r' % socket.gethostname() +def blender_id_session(): + """Returns the Requests session, creating it if necessary.""" + global requests_session + import requests + + if requests_session is not None: + return requests_session + + requests_session = requests.session() + + # Retry with backoff factor, so that a restart of Blender ID or hickup + # in the connection doesn't immediately fail the request. + retries = requests.packages.urllib3.util.retry.Retry( + total=10, + backoff_factor=0.05, + ) + http_adapter = requests.adapters.HTTPAdapter(max_retries=retries) + requests_session.mount('https://', http_adapter) + requests_session.mount('http://', http_adapter) + + # Construct the User-Agent header with Blender and add-on versions. + try: + import bpy + except ImportError: + blender_version = 'unknown' + else: + blender_version = '.'.join(str(component) for component in bpy.app.version) + + from blender_id import bl_info + addon_version = '.'.join(str(component) for component in bl_info['version']) + requests_session.headers['User-Agent'] = f'Blender/{blender_version} Blender-ID-Addon/{addon_version}' + + return requests_session + + @functools.lru_cache(maxsize=None) def blender_id_endpoint(endpoint_path=None): """Gets the endpoint for the authentication API. If the BLENDER_ID_ENDPOINT env variable @@ -80,7 +118,6 @@ def blender_id_server_authenticate(username, password) -> AuthResult: message. Problems may be with the connection or wrong user/password. """ - import requests import requests.exceptions payload = dict( @@ -90,8 +127,9 @@ def blender_id_server_authenticate(username, password) -> AuthResult: ) url = blender_id_endpoint('u/identify') + session = blender_id_session() try: - r = requests.post(url, data=payload, verify=True) + r = session.post(url, data=payload, verify=True) except (requests.exceptions.SSLError, requests.exceptions.HTTPError, requests.exceptions.ConnectionError) as e: @@ -126,12 +164,12 @@ def blender_id_server_validate(token) -> typing.Tuple[typing.Optional[str], typi The error is None if the token is valid, or an error message when it's invalid. """ - import requests import requests.exceptions url = blender_id_endpoint('u/validate_token') + session = blender_id_session() try: - r = requests.post(url, data={'token': token}, verify=True) + r = session.post(url, data={'token': token}, verify=True) except requests.exceptions.ConnectionError: log.exception('error connecting to Blender ID at %s', url) return None, 'Unable to connect to Blender ID' @@ -157,16 +195,16 @@ def blender_id_server_logout(user_id, token): @rtype: dict """ - import requests import requests.exceptions payload = dict( user_id=user_id, token=token ) + session = blender_id_session() try: - r = requests.post(blender_id_endpoint('u/delete_token'), - data=payload, verify=True) + r = session.post(blender_id_endpoint('u/delete_token'), + data=payload, verify=True) except (requests.exceptions.SSLError, requests.exceptions.HTTPError, requests.exceptions.ConnectionError) as e: @@ -217,15 +255,15 @@ def subclient_create_token(auth_token: str, subclient_id: str) -> dict: def make_authenticated_call(method, url, auth_token, data): """Makes a HTTP call authenticated with the OAuth token.""" - import requests import requests.exceptions + session = blender_id_session() try: - r = requests.request(method, - blender_id_endpoint(url), - data=data, - headers={'Authorization': 'Bearer %s' % auth_token}, - verify=True) + r = session.request(method, + blender_id_endpoint(url), + data=data, + headers={'Authorization': 'Bearer %s' % auth_token}, + verify=True) except (requests.exceptions.HTTPError, requests.exceptions.ConnectionError) as e: raise BlenderIdCommError(str(e)) @@ -244,16 +282,17 @@ def send_token_to_subclient(webservice_endpoint: str, user_id: str, :returns: the user ID at the subclient. """ - import requests + import requests.exceptions import urllib.parse url = urllib.parse.urljoin(webservice_endpoint, 'blender_id/store_scst') + session = blender_id_session() try: - r = requests.post(url, - data={'user_id': user_id, - 'subclient_id': subclient_id, - 'token': subclient_token}, - verify=True) + r = session.post(url, + data={'user_id': user_id, + 'subclient_id': subclient_id, + 'token': subclient_token}, + verify=True) r.raise_for_status() except (requests.exceptions.HTTPError, requests.exceptions.ConnectionError) as e: |