summaryrefslogtreecommitdiff
path: root/openstackclient
diff options
context:
space:
mode:
authorDean Troyer <dtroyer@gmail.com>2015-04-13 16:47:49 -0500
committerDean Troyer <dtroyer@gmail.com>2015-04-15 22:40:52 -0500
commitf43c1f76559ae8b5b738b7ae8b69b15c379f9145 (patch)
tree0312547c04ebfc6ae09119b734945e6bbfcbb651 /openstackclient
parente60bf28ae3bdb34b65316249f0e7615048aa1f95 (diff)
downloadpython-openstackclient-f43c1f76559ae8b5b738b7ae8b69b15c379f9145.tar.gz
Defer client imports
So we really weren't deferring the loading of client libs dadgummit, do that for real where possible. This shaves a couple of tenths off the static import times. Also defer as much import-time procesing as possible. This is a little ugly in api.auth but this also eliminates import of the auth plugins until they are needed. Change-Id: Ia11d4b9cf98231d37449103fc29101dc17afb009
Diffstat (limited to 'openstackclient')
-rw-r--r--openstackclient/api/auth.py64
-rw-r--r--openstackclient/compute/client.py17
-rw-r--r--openstackclient/tests/common/test_clientmanager.py4
-rw-r--r--openstackclient/tests/volume/test_find_resource.py7
-rw-r--r--openstackclient/volume/client.py20
5 files changed, 73 insertions, 39 deletions
diff --git a/openstackclient/api/auth.py b/openstackclient/api/auth.py
index ba51bee1..ffbcb6fc 100644
--- a/openstackclient/api/auth.py
+++ b/openstackclient/api/auth.py
@@ -27,29 +27,49 @@ from openstackclient.i18n import _
LOG = logging.getLogger(__name__)
-
# Initialize the list of Authentication plugins early in order
# to get the command-line options
-PLUGIN_LIST = stevedore.ExtensionManager(
- base.PLUGIN_NAMESPACE,
- invoke_on_load=False,
- propagate_map_exceptions=True,
-)
+PLUGIN_LIST = None
-# Get the command line options so the help action has them available
+# List of plugin command line options
OPTIONS_LIST = {}
-for plugin in PLUGIN_LIST:
- for o in plugin.plugin.get_options():
- os_name = o.dest.lower().replace('_', '-')
- os_env_name = 'OS_' + os_name.upper().replace('-', '_')
- OPTIONS_LIST.setdefault(os_name, {'env': os_env_name, 'help': ''})
- # TODO(mhu) simplistic approach, would be better to only add
- # help texts if they vary from one auth plugin to another
- # also the text rendering is ugly in the CLI ...
- OPTIONS_LIST[os_name]['help'] += 'With %s: %s\n' % (
- plugin.name,
- o.help,
+
+
+def get_plugin_list():
+ """Gather plugin list and cache it"""
+
+ global PLUGIN_LIST
+
+ if PLUGIN_LIST is None:
+ PLUGIN_LIST = stevedore.ExtensionManager(
+ base.PLUGIN_NAMESPACE,
+ invoke_on_load=False,
+ propagate_map_exceptions=True,
)
+ return PLUGIN_LIST
+
+
+def get_options_list():
+ """Gather plugin options so the help action has them available"""
+
+ global OPTIONS_LIST
+
+ if not OPTIONS_LIST:
+ for plugin in get_plugin_list():
+ for o in plugin.plugin.get_options():
+ os_name = o.dest.lower().replace('_', '-')
+ os_env_name = 'OS_' + os_name.upper().replace('-', '_')
+ OPTIONS_LIST.setdefault(
+ os_name, {'env': os_env_name, 'help': ''},
+ )
+ # TODO(mhu) simplistic approach, would be better to only add
+ # help texts if they vary from one auth plugin to another
+ # also the text rendering is ugly in the CLI ...
+ OPTIONS_LIST[os_name]['help'] += 'With %s: %s\n' % (
+ plugin.name,
+ o.help,
+ )
+ return OPTIONS_LIST
def select_auth_plugin(options):
@@ -57,7 +77,7 @@ def select_auth_plugin(options):
auth_plugin_name = None
- if options.os_auth_type in [plugin.name for plugin in PLUGIN_LIST]:
+ if options.os_auth_type in [plugin.name for plugin in get_plugin_list()]:
# A direct plugin name was given, use it
return options.os_auth_type
@@ -113,7 +133,7 @@ def build_auth_params(auth_plugin_name, cmd_options):
else:
LOG.debug('no auth_type')
# delay the plugin choice, grab every option
- plugin_options = set([o.replace('-', '_') for o in OPTIONS_LIST])
+ plugin_options = set([o.replace('-', '_') for o in get_options_list()])
for option in plugin_options:
option_name = 'os_' + option
LOG.debug('fetching option %s' % option_name)
@@ -147,7 +167,7 @@ def build_auth_plugins_option_parser(parser):
authentication plugin.
"""
- available_plugins = [plugin.name for plugin in PLUGIN_LIST]
+ available_plugins = [plugin.name for plugin in get_plugin_list()]
parser.add_argument(
'--os-auth-type',
metavar='<auth-type>',
@@ -169,7 +189,7 @@ def build_auth_plugins_option_parser(parser):
default=utils.env('OS_TENANT_ID')
),
}
- for o in OPTIONS_LIST:
+ for o in get_options_list():
# remove allusion to tenants from v2.0 API
if 'tenant' not in o:
parser.add_argument(
diff --git a/openstackclient/compute/client.py b/openstackclient/compute/client.py
index 7ca08a4f..461c3926 100644
--- a/openstackclient/compute/client.py
+++ b/openstackclient/compute/client.py
@@ -15,14 +15,6 @@
import logging
-from novaclient import client as nova_client
-from novaclient import extension
-
-try:
- from novaclient.v2.contrib import list_extensions
-except ImportError:
- from novaclient.v1_1.contrib import list_extensions
-
from openstackclient.common import utils
LOG = logging.getLogger(__name__)
@@ -34,6 +26,15 @@ API_NAME = 'compute'
def make_client(instance):
"""Returns a compute service client."""
+
+ # Defer client imports until we actually need them
+ from novaclient import client as nova_client
+ from novaclient import extension
+ try:
+ from novaclient.v2.contrib import list_extensions
+ except ImportError:
+ from novaclient.v1_1.contrib import list_extensions
+
compute_client = nova_client.get_client_class(
instance._api_version[API_NAME],
)
diff --git a/openstackclient/tests/common/test_clientmanager.py b/openstackclient/tests/common/test_clientmanager.py
index 3648bf57..7a2f57be 100644
--- a/openstackclient/tests/common/test_clientmanager.py
+++ b/openstackclient/tests/common/test_clientmanager.py
@@ -34,6 +34,10 @@ AUTH_REF.update(fakes.TEST_RESPONSE_DICT['access'])
SERVICE_CATALOG = service_catalog.ServiceCatalogV2(AUTH_REF)
+# This is deferred in api.auth but we need it here...
+auth.get_options_list()
+
+
class Container(object):
attr = clientmanager.ClientCache(lambda x: object())
diff --git a/openstackclient/tests/volume/test_find_resource.py b/openstackclient/tests/volume/test_find_resource.py
index 56081966..00cc46a6 100644
--- a/openstackclient/tests/volume/test_find_resource.py
+++ b/openstackclient/tests/volume/test_find_resource.py
@@ -24,6 +24,13 @@ from openstackclient.tests import utils as test_utils
from openstackclient.volume import client # noqa
+# Monkey patch for v1 cinderclient
+# NOTE(dtroyer): Do here because openstackclient.volume.client
+# doesn't do it until the client object is created now.
+volumes.Volume.NAME_ATTR = 'display_name'
+volume_snapshots.Snapshot.NAME_ATTR = 'display_name'
+
+
ID = '1after909'
NAME = 'PhilSpector'
diff --git a/openstackclient/volume/client.py b/openstackclient/volume/client.py
index 21072aeb..a7b64def 100644
--- a/openstackclient/volume/client.py
+++ b/openstackclient/volume/client.py
@@ -15,17 +15,8 @@
import logging
-from cinderclient import extension
-from cinderclient.v1.contrib import list_extensions
-from cinderclient.v1 import volume_snapshots
-from cinderclient.v1 import volumes
-
from openstackclient.common import utils
-# Monkey patch for v1 cinderclient
-volumes.Volume.NAME_ATTR = 'display_name'
-volume_snapshots.Snapshot.NAME_ATTR = 'display_name'
-
LOG = logging.getLogger(__name__)
DEFAULT_VOLUME_API_VERSION = '1'
@@ -38,6 +29,17 @@ API_VERSIONS = {
def make_client(instance):
"""Returns a volume service client."""
+
+ # Defer client imports until we actually need them
+ from cinderclient import extension
+ from cinderclient.v1.contrib import list_extensions
+ from cinderclient.v1 import volume_snapshots
+ from cinderclient.v1 import volumes
+
+ # Monkey patch for v1 cinderclient
+ volumes.Volume.NAME_ATTR = 'display_name'
+ volume_snapshots.Snapshot.NAME_ATTR = 'display_name'
+
volume_client = utils.get_client_class(
API_NAME,
instance._api_version[API_NAME],