diff --git a/HISTORY.rst b/HISTORY.rst index a437a47d..e9f2988b 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -4,6 +4,11 @@ Shotgun Python API Changelog Here you can see the full list of changes between each Python API release. +v3.1.2 (2019 Sept 17) +===================== +- Adds an optional `localized` property on the Shotgun object which allows to retrieve localized display names on + methods ``schema_entity_read()``, ``schema_field_read()``, and ``schema_read()``. + v3.1.1 (2019 August 29) ===================== - Fixes a regression on Python 2.7.0-2.7.9 on Windows with the mimetypes module. diff --git a/docs/reference.rst b/docs/reference.rst index c39facc0..d5f68d99 100644 --- a/docs/reference.rst +++ b/docs/reference.rst @@ -891,3 +891,46 @@ Stores the number of milliseconds to wait between request retries. By default, In the case that both this environment variable and the config's ``rpc_attempt_interval`` property are set, the value in ``rpc_attempt_interal`` will be used. +************ +Localization +************ + +The Shotgun API offers the ability to return localized display names in the current user's language. +Requests made from script/API users are localized in the site settings. + +This functionality is currently supported by the methods ``Shotgun.schema_entity_read``, ``Shotgun.schema_field_read``, and ``Shotgun.schema_read``. + +Localization is disabled by default. To enable localization, set the ``localized`` property to ``True``. + +Example for a user whose language preference is set to Japanese: + +.. code-block:: python + :emphasize-lines: 9,20 + + >>> sg = Shotgun(site_name, script_name, script_key) + >>> sg.config.localized # checking that localization is disabled + False + >>> sg.schema_field_read('Shot') + { + 'sg_vendor_groups': { + 'mandatory': {'editable': False, 'value': False}, + # the value field (display name) is not localized + 'name': {'editable': True, 'value': 'Vendor Groups'}, + ... + }, + ... + } + >>> sg.config.localized = True # enabling the localization + >>> sg.schema_field_read('Shot') + { + 'sg_vendor_groups': { + 'mandatory': {'editable': False, 'value': False}, + # the value field (display name) is localized + 'name': {'editable': True, 'value': '\xe3\x83\x99\xe3\x83\xb3\xe3\x83\x80\xe3\x83\xbc \xe3\x82\xb0\xe3\x83\xab\xe3\x83\xbc\xe3\x83\x97'}, + ... + }, + ... + } + +.. note:: + If needed, the encoding of the returned localized string can be ensured regardless the Python version using shotgun_api3.lib.six.ensure_text(). diff --git a/setup.py b/setup.py index e925bdd4..8837466c 100644 --- a/setup.py +++ b/setup.py @@ -27,7 +27,7 @@ setup( name='shotgun_api3', - version='3.1.1', + version='3.1.2', description='Shotgun Python API ', long_description=readme, author='Shotgun Software', diff --git a/shotgun_api3/shotgun.py b/shotgun_api3/shotgun.py index 151394ed..5395696c 100755 --- a/shotgun_api3/shotgun.py +++ b/shotgun_api3/shotgun.py @@ -117,7 +117,7 @@ def _is_mimetypes_broken(): # ---------------------------------------------------------------------------- # Version -__version__ = "3.1.1" +__version__ = "3.1.2" # ---------------------------------------------------------------------------- # Errors @@ -427,6 +427,7 @@ def __init__(self, sg): self.session_token = None self.authorization = None self.no_ssl_validation = False + self.localized = False @property def records_per_page(self): @@ -1818,6 +1819,9 @@ def schema_entity_read(self, project_entity=None): ``{'type': 'Project', 'id': 3}`` :returns: dict of Entity Type to dict containing the display name. :rtype: dict + + .. note:: + The returned display names for this method will be localized when the ``localize`` Shotgun config property is set to ``True``. See :ref:`localization` for more information. """ params = {} @@ -1887,6 +1891,9 @@ def schema_read(self, project_entity=None): types. Properties that are ``'editable': True``, can be updated using the :meth:`~shotgun_api3.Shotgun.schema_field_update` method. :rtype: dict + + .. note:: + The returned display names for this method will be localized when the ``localize`` Shotgun config property is set to ``True``. See :ref:`localization` for more information. """ params = {} @@ -1917,6 +1924,9 @@ def schema_field_read(self, entity_type, field_name=None, project_entity=None): .. note:: If you don't specify a ``project_entity``, everything is reported as visible. + .. note:: + The returned display names for this method will be localized when the ``localize`` Shotgun config property is set to ``True``. See :ref:`localization` for more information. + >>> sg.schema_field_read('Asset', 'shots') {'shots': {'data_type': {'editable': False, 'value': 'multi_entity'}, 'description': {'editable': True, 'value': ''}, @@ -3205,6 +3215,10 @@ def _call_rpc(self, method, params, include_auth_params=True, first=False): "content-type": "application/json; charset=utf-8", "connection": "keep-alive" } + + if self.config.localized is True: + req_headers["locale"] = "auto" + http_status, resp_headers, body = self._make_call("POST", self.config.api_path, encoded_payload, req_headers) LOG.debug("Completed rpc call to %s" % (method)) diff --git a/tests/example_config b/tests/example_config index 3ced7dc7..451b10dd 100644 --- a/tests/example_config +++ b/tests/example_config @@ -15,6 +15,7 @@ # Full url to the Shotgun server server # e.g. http://my-company.shotgunstudio.com +# be careful to not end server_url with a "/", or some tests may fail server_url : http://0.0.0.0:3000 # script name as key as listed in admin panel for your server script_name : test script name diff --git a/tests/test_client.py b/tests/test_client.py index 74ddb4d1..ae74b575 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -184,6 +184,28 @@ def test_authorization(self): expected = "Basic " + b64encode(urllib.parse.unquote(login_password)).strip() self.assertEqual(expected, headers.get("Authorization")) + def test_localization_header_default(self): + """Localization header not passed to server without explicitly setting SG localization config to True""" + self.sg.info() + + args, _ = self.sg._http_request.call_args + (_, _, _, headers) = args + expected_header_value = "auto" + + self.assertEqual(None, headers.get("locale")) + + def test_localization_header_when_localized(self): + """Localization header passed to server when setting SG localization config to True""" + self.sg.config.localized = True + + self.sg.info() + + args, _ = self.sg._http_request.call_args + (_, _, _, headers) = args + expected_header_value = "auto" + + self.assertEqual("auto", headers.get("locale")) + def test_user_agent(self): """User-Agent passed to server""" # test default user agent