Skip to content
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
a30575a
Implement conditional autoprompt importing.
aemous Apr 15, 2026
c2a322c
Minor formatting change.
aemous Apr 20, 2026
8762f7a
Fix tests based on new autoprompt interface.
aemous Apr 20, 2026
389cd83
Fix remaining eager imports of prompttoolkit and autoprompt.
aemous Apr 20, 2026
e82544d
Add new autoprompt.exceptions file.
aemous Apr 20, 2026
4a96adf
Refactor Configure SSO and SSOSession commands to achieve lazy import…
aemous Apr 20, 2026
9491794
Remove year from license in sso_commands.py file.
aemous Apr 20, 2026
50f107e
Add module-level comment explaining new sso_commands.py module.
aemous Apr 20, 2026
05b657e
Fix bug where provided runners on wizardcommands were not being propo…
aemous Apr 21, 2026
bf888ff
Add changelog entry.
aemous Apr 21, 2026
2e7ae88
Update enhancement-Performance-97002.json
aemous Apr 24, 2026
4a3cf3b
Defer import of prompt_toolkit for 'aws configure' commands until the…
aemous Apr 24, 2026
de3aad1
Refactor logs customization to defer prompt_toolkit imports.
aemous Apr 27, 2026
adee5c9
Rename test file and update imports after logs refactor.
aemous Apr 27, 2026
509f9b3
Changes based on feedback.
aemous Apr 28, 2026
cc38ce1
First pass of pre-commit.
aemous Apr 28, 2026
f82c3f8
Second pass of pre-commit.
aemous Apr 28, 2026
4400280
Third pass of pre-commit
aemous Apr 28, 2026
f24425b
Fix new tests on Windows by porting existing BaseAWSCommandParamsTest…
aemous Apr 28, 2026
7542c33
Raise timeout to 60s in new tests to address flakiness on Windows run…
aemous Apr 29, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changes/next-release/enhancement-Performance-97002.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"type": "enhancement",
"category": "Performance",
"description": "Defer some imports (e.g. ``prompt_toolkit``) until they are needed to reduce command initialization time (e.g. loading all imported modules)."
}
29 changes: 0 additions & 29 deletions awscli/autoprompt/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
from awscli.autocomplete.filters import fuzzy_filter
from awscli.autocomplete.main import create_autocompleter
from awscli.autoprompt.prompttoolkit import PromptToolkitPrompter
from awscli.customizations.exceptions import ParamValidationError
from awscli.errorhandler import SilenceParamValidationMsgErrorHandler


Expand All @@ -42,34 +41,6 @@ def prompter(self):
)
return self._prompter

def validate_auto_prompt_args_are_mutually_exclusive(self, args):
no_cli_auto_prompt = self._NO_CLI_AUTO_PROMPT_OPTION in args
cli_auto_prompt = self._CLI_AUTO_PROMPT_OPTION in args
if cli_auto_prompt and no_cli_auto_prompt:
raise ParamValidationError(
'Both --cli-auto-prompt and --no-cli-auto-prompt cannot be '
'specified at the same time.'
)

def resolve_mode(self, args):
# Order of precedence to check:
# - check if any arg rom NO_PROMPT_ARGS in args
# - check if '--no-cli-auto-prompt' was specified
# - check if '--cli-auto-prompt' was specified
# - check configuration chain
self.validate_auto_prompt_args_are_mutually_exclusive(args)
if any(arg in args for arg in self._NO_PROMPT_ARGS):
return 'off'
if self._NO_CLI_AUTO_PROMPT_OPTION in args:
return 'off'
if self._CLI_AUTO_PROMPT_OPTION in args:
return 'on'
try:
config = self._session.get_config_variable('cli_auto_prompt')
return config.lower()
except ProfileNotFound:
return 'off'

def inject_silence_param_error_msg_handler(self, driver):
driver.error_handler.inject_handler(
0, SilenceParamValidationMsgErrorHandler()
Expand Down
2 changes: 2 additions & 0 deletions awscli/autoprompt/exceptions.py
Comment thread
aemous marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
class PrompterKeyboardInterrupt(KeyboardInterrupt):
pass
3 changes: 1 addition & 2 deletions awscli/autoprompt/factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,7 @@
)


class PrompterKeyboardInterrupt(KeyboardInterrupt):
pass
from awscli.autoprompt.exceptions import PrompterKeyboardInterrupt


class CLIPromptBuffer(Buffer):
Expand Down
44 changes: 41 additions & 3 deletions awscli/clidriver.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
import re
import sys

from botocore.exceptions import ProfileNotFound

import botocore.session
import distro
from botocore import xform_name
Expand Down Expand Up @@ -49,7 +51,6 @@
ListArgument,
UnknownArgumentError,
)
from awscli.autoprompt.core import AutoPromptDriver
from awscli.commands import CLICommand
from awscli.compat import (
default_pager,
Expand Down Expand Up @@ -83,13 +84,17 @@
add_metadata_component_to_user_agent_extra,
emit_top_level_args_parsed_event,
)
from awscli.customizations.exceptions import ParamValidationError

LOG = logging.getLogger('awscli.clidriver')
LOG_FORMAT = (
'%(asctime)s - %(threadName)s - %(name)s - %(levelname)s - %(message)s'
)
HISTORY_RECORDER = get_global_history_recorder()
METADATA_FILENAME = 'metadata.json'
_NO_AUTO_PROMPT_ARGS = ['help', '--version']
_CLI_AUTO_PROMPT_OPTION = '--cli-auto-prompt'
_NO_CLI_AUTO_PROMPT_OPTION = '--no-cli-auto-prompt'
# Don't remove this line. The idna encoding
# is used by getaddrinfo when dealing with unicode hostnames,
# and in some cases, there appears to be a race condition
Expand Down Expand Up @@ -126,6 +131,36 @@ def create_clidriver(args=None):
return driver


def validate_auto_prompt_args_are_mutually_exclusive(args):
no_cli_auto_prompt = _NO_CLI_AUTO_PROMPT_OPTION in args
cli_auto_prompt = _CLI_AUTO_PROMPT_OPTION in args
if cli_auto_prompt and no_cli_auto_prompt:
raise ParamValidationError(
'Both --cli-auto-prompt and --no-cli-auto-prompt cannot be '
'specified at the same time.'
)


def resolve_auto_prompt_mode(args, session):
# Order of precedence to check:
# - check if any arg rom NO_PROMPT_ARGS in args
Comment thread
aemous marked this conversation as resolved.
Outdated
# - check if '--no-cli-auto-prompt' was specified
# - check if '--cli-auto-prompt' was specified
# - check configuration chain
validate_auto_prompt_args_are_mutually_exclusive(args)
if any(arg in args for arg in _NO_AUTO_PROMPT_ARGS):
return 'off'
if _NO_CLI_AUTO_PROMPT_OPTION in args:
return 'off'
if _CLI_AUTO_PROMPT_OPTION in args:
return 'on'
try:
config = session.get_config_variable('cli_auto_prompt')
return config.lower()
except ProfileNotFound:
return 'off'


def _get_distribution_source():
metadata_file = os.path.join(
os.path.join(os.path.dirname(os.path.abspath(__file__)), 'data'),
Expand Down Expand Up @@ -220,12 +255,15 @@ def _do_main(self, args):
driver = self._driver
if driver is None:
driver = create_clidriver(args)
autoprompt_driver = AutoPromptDriver(driver)
auto_prompt_mode = autoprompt_driver.resolve_mode(args)
auto_prompt_mode = resolve_auto_prompt_mode(args, driver.session)
if auto_prompt_mode == 'on':
from awscli.autoprompt.core import AutoPromptDriver
autoprompt_driver = AutoPromptDriver(driver)
args = autoprompt_driver.prompt_for_args(args)
rc = self._run_driver(driver, args, prompt_mode='on')
elif auto_prompt_mode == 'on-partial':
from awscli.autoprompt.core import AutoPromptDriver
autoprompt_driver = AutoPromptDriver(driver)
autoprompt_driver.inject_silence_param_error_msg_handler(driver)
rc = self._run_driver(driver, args, prompt_mode='off')
if rc == PARAM_VALIDATION_ERROR_RC:
Expand Down
2 changes: 1 addition & 1 deletion awscli/customizations/configure/configure.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
from awscli.customizations.configure.listprofiles import ListProfilesCommand
from awscli.customizations.configure.mfalogin import ConfigureMFALoginCommand
from awscli.customizations.configure.set import ConfigureSetCommand
from awscli.customizations.configure.sso import (
from awscli.customizations.configure.sso_commands import (
ConfigureSSOCommand,
ConfigureSSOSessionCommand,
)
Expand Down
Loading
Loading