diff --git a/openstackclient/api/api.py b/openstackclient/api/api.py
index 0b00ff5067..04d88f31e9 100644
--- a/openstackclient/api/api.py
+++ b/openstackclient/api/api.py
@@ -19,6 +19,8 @@ from keystoneauth1 import exceptions as ks_exceptions
 from keystoneauth1 import session as ks_session
 from osc_lib import exceptions
 
+from openstackclient.i18n import _
+
 
 class KeystoneSession(object):
     """Wrapper for the Keystone Session
@@ -254,9 +256,11 @@ class BaseAPI(KeystoneSession):
         if len(data) == 1:
             return data[0]
         if len(data) > 1:
-            msg = "Multiple %s exist with %s='%s'"
+            msg = _("Multiple %(resource)s exist with %(attr)s='%(value)s'")
             raise exceptions.CommandError(
-                msg % (resource, attr, value),
+                msg % {'resource': resource,
+                       'attr': attr,
+                       'value': value}
             )
 
         # Search by id
@@ -264,8 +268,12 @@ class BaseAPI(KeystoneSession):
         data = getlist(kwargs)
         if len(data) == 1:
             return data[0]
-        msg = "No %s with a %s or ID of '%s' found"
-        raise exceptions.CommandError(msg % (resource, attr, value))
+        msg = _("No %(resource)s with a %(attr)s or ID of '%(value)s' found")
+        raise exceptions.CommandError(
+            msg % {'resource': resource,
+                   'attr': attr,
+                   'value': value}
+        )
 
     def find_bulk(
         self,
@@ -313,10 +321,10 @@ class BaseAPI(KeystoneSession):
         bulk_list = self.find_bulk(path, **kwargs)
         num_bulk = len(bulk_list)
         if num_bulk == 0:
-            msg = "none found"
+            msg = _("none found")
             raise exceptions.NotFound(msg)
         elif num_bulk > 1:
-            msg = "many found"
+            msg = _("many found")
             raise RuntimeError(msg)
         return bulk_list[0]
 
@@ -343,7 +351,7 @@ class BaseAPI(KeystoneSession):
             try:
                 ret = self.find_one("/%s/detail" % (path), **kwargs)
             except ks_exceptions.NotFound:
-                msg = "%s not found" % value
+                msg = _("%s not found") % value
                 raise exceptions.NotFound(msg)
 
         return ret
diff --git a/openstackclient/api/auth.py b/openstackclient/api/auth.py
index a55af29389..b56035e4dd 100644
--- a/openstackclient/api/auth.py
+++ b/openstackclient/api/auth.py
@@ -171,7 +171,8 @@ def check_valid_auth_options(options, auth_plugin_name, required_scope=True):
                           'auth.url'))
 
     if msgs:
-        raise exc.CommandError('Missing parameter(s): \n%s' % '\n'.join(msgs))
+        raise exc.CommandError(
+            _('Missing parameter(s): \n%s') % '\n'.join(msgs))
 
 
 def build_auth_plugins_option_parser(parser):
@@ -187,10 +188,9 @@ def build_auth_plugins_option_parser(parser):
         metavar='<auth-type>',
         dest='auth_type',
         default=utils.env('OS_AUTH_TYPE'),
-        help='Select an authentication type. Available types: ' +
-             ', '.join(available_plugins) +
-             '. Default: selected based on --os-username/--os-token' +
-             ' (Env: OS_AUTH_TYPE)',
+        help=_('Select an authentication type. Available types: %s.'
+               ' Default: selected based on --os-username/--os-token'
+               ' (Env: OS_AUTH_TYPE)') % ', '.join(available_plugins),
         choices=available_plugins
     )
     # Maintain compatibility with old tenant env vars
@@ -215,10 +215,10 @@ def build_auth_plugins_option_parser(parser):
                     OPTIONS_LIST[o]['env'],
                     utils.env(OPTIONS_LIST[o]['env']),
                 ),
-                help='%s\n(Env: %s)' % (
-                    OPTIONS_LIST[o]['help'],
-                    OPTIONS_LIST[o]['env'],
-                ),
+                help=_('%(help)s\n(Env: %(env)s)') % {
+                    'help': OPTIONS_LIST[o]['help'],
+                    'env': OPTIONS_LIST[o]['env'],
+                },
             )
     # add tenant-related options for compatibility
     # this is deprecated but still used in some tempest tests...
diff --git a/openstackclient/api/auth_plugin.py b/openstackclient/api/auth_plugin.py
index 44d3b38ea4..36dc51605f 100644
--- a/openstackclient/api/auth_plugin.py
+++ b/openstackclient/api/auth_plugin.py
@@ -21,6 +21,8 @@ from six.moves.urllib import parse as urlparse
 from keystoneauth1.loading._plugins import admin_token as token_endpoint
 from keystoneauth1.loading._plugins.identity import generic as ksa_password
 
+from openstackclient.i18n import _
+
 LOG = logging.getLogger(__name__)
 
 
@@ -51,10 +53,10 @@ class TokenEndpoint(token_endpoint.AdminToken):
         options.extend([
             # Maintain name 'url' for compatibility
             cfg.StrOpt('url',
-                       help='Specific service endpoint to use'),
+                       help=_('Specific service endpoint to use')),
             cfg.StrOpt('token',
                        secret=True,
-                       help='Authentication token to use'),
+                       help=_('Authentication token to use')),
         ])
 
         return options
diff --git a/openstackclient/shell.py b/openstackclient/shell.py
index a15e04dd69..12a63af219 100644
--- a/openstackclient/shell.py
+++ b/openstackclient/shell.py
@@ -36,6 +36,7 @@ from oslo_utils import strutils
 import openstackclient
 from openstackclient.common import clientmanager
 from openstackclient.common import commandmanager
+from openstackclient.i18n import _
 
 from os_client_config import config as cloud_config
 
@@ -63,9 +64,8 @@ def prompt_for_password(prompt=None):
             pass
     # No password because we did't have a tty or nothing was entered
     if not pw:
-        raise exc.CommandError(
-            "No password entered, or found via --os-password or OS_PASSWORD",
-        )
+        raise exc.CommandError(_("No password entered, or found via"
+                                 " --os-password or OS_PASSWORD"),)
     return pw
 
 
@@ -185,7 +185,7 @@ class OpenStackShell(app.App):
             metavar='<cloud-config-name>',
             dest='cloud',
             default=utils.env('OS_CLOUD'),
-            help='Cloud name in clouds.yaml (Env: OS_CLOUD)',
+            help=_('Cloud name in clouds.yaml (Env: OS_CLOUD)'),
         )
         # Global arguments
         parser.add_argument(
@@ -193,37 +193,41 @@ class OpenStackShell(app.App):
             metavar='<auth-region-name>',
             dest='region_name',
             default=utils.env('OS_REGION_NAME'),
-            help='Authentication region name (Env: OS_REGION_NAME)')
+            help=_('Authentication region name (Env: OS_REGION_NAME)'),
+        )
         parser.add_argument(
             '--os-cacert',
             metavar='<ca-bundle-file>',
             dest='cacert',
             default=utils.env('OS_CACERT'),
-            help='CA certificate bundle file (Env: OS_CACERT)')
+            help=_('CA certificate bundle file (Env: OS_CACERT)'),
+        )
         parser.add_argument(
             '--os-cert',
             metavar='<certificate-file>',
             dest='cert',
             default=utils.env('OS_CERT'),
-            help='Client certificate bundle file (Env: OS_CERT)')
+            help=_('Client certificate bundle file (Env: OS_CERT)'),
+        )
         parser.add_argument(
             '--os-key',
             metavar='<key-file>',
             dest='key',
             default=utils.env('OS_KEY'),
-            help='Client certificate key file (Env: OS_KEY)')
+            help=_('Client certificate key file (Env: OS_KEY)'),
+        )
         verify_group = parser.add_mutually_exclusive_group()
         verify_group.add_argument(
             '--verify',
             action='store_true',
             default=None,
-            help='Verify server certificate (default)',
+            help=_('Verify server certificate (default)'),
         )
         verify_group.add_argument(
             '--insecure',
             action='store_true',
             default=None,
-            help='Disable server certificate verification',
+            help=_('Disable server certificate verification'),
         )
         parser.add_argument(
             '--os-default-domain',
@@ -232,28 +236,29 @@ class OpenStackShell(app.App):
             default=utils.env(
                 'OS_DEFAULT_DOMAIN',
                 default=DEFAULT_DOMAIN),
-            help='Default domain ID, default=' +
-                 DEFAULT_DOMAIN +
-                 ' (Env: OS_DEFAULT_DOMAIN)')
+            help=_('Default domain ID, default=%s. '
+                   '(Env: OS_DEFAULT_DOMAIN)') % DEFAULT_DOMAIN,
+        )
         parser.add_argument(
             '--os-interface',
             metavar='<interface>',
             dest='interface',
             choices=['admin', 'public', 'internal'],
             default=utils.env('OS_INTERFACE'),
-            help='Select an interface type.'
-                 ' Valid interface types: [admin, public, internal].'
-                 ' (Env: OS_INTERFACE)')
+            help=_('Select an interface type.'
+                   ' Valid interface types: [admin, public, internal].'
+                   ' (Env: OS_INTERFACE)'),
+        )
         parser.add_argument(
             '--timing',
             default=False,
             action='store_true',
-            help="Print API call timing info",
+            help=_("Print API call timing info"),
         )
         parser.add_argument(
             '--os-beta-command',
             action='store_true',
-            help="Enable beta commands which are subject to change",
+            help=_("Enable beta commands which are subject to change"),
         )
 
         # osprofiler HMAC key argument
@@ -262,7 +267,7 @@ class OpenStackShell(app.App):
                 '--os-profile',
                 metavar='hmac-key',
                 dest='profile',
-                help='HMAC key for encrypting profiling context data',
+                help=_('HMAC key for encrypting profiling context data'),
             )
             # NOTE(dtroyer): This global option should have been named
             #                --os-profile as --profile interferes with at