Skip to content

Commit

Permalink
Apply Review
Browse files Browse the repository at this point in the history
  • Loading branch information
mbercx committed Jun 19, 2024
1 parent c9ca0d7 commit e87eb5c
Show file tree
Hide file tree
Showing 15 changed files with 116 additions and 85 deletions.
52 changes: 31 additions & 21 deletions docs/source/reference/command_line.rst
Original file line number Diff line number Diff line change
Expand Up @@ -329,23 +329,27 @@ Below is a list with all available subcommands.
the newly created profile uses the new PostgreSQL database instead of SQLite.
Options:
--profile-name TEXT Name of the profile. By default, a unique name starting with
`presto` is automatically generated. [default: (dynamic)]
--email TEXT Email of the default user. [default: (dynamic)]
--use-postgres When toggled on, the profile uses a PostgreSQL database
instead of an SQLite one. The connection details to the
PostgreSQL server can be configured with the relevant options.
The command attempts to automatically create a user and
database to use for the profile, but this can fail depending
on the configuration of the server.
--postgres-hostname TEXT The hostname of the PostgreSQL server.
--postgres-port INTEGER The port of the PostgreSQL server.
--postgres-username TEXT The username of the PostgreSQL user that is authorized to
create new databases.
--postgres-password TEXT The password of the PostgreSQL user that is authorized to
create new databases.
-n, --non-interactive Never prompt, such as for sudo password.
--help Show this message and exit.
--profile-name TEXT Name of the profile. By default, a unique name starting
with `presto` is automatically generated. [default:
(dynamic)]
--email TEXT Email of the default user. [default: (dynamic)]
--use-postgres When toggled on, the profile uses a PostgreSQL database
instead of an SQLite one. The connection details to the
PostgreSQL server can be configured with the relevant
options. The command attempts to automatically create a
user and database to use for the profile, but this can
fail depending on the configuration of the server.
--postgres-hostname TEXT The hostname of the PostgreSQL server.
--postgres-port INTEGER The port of the PostgreSQL server.
--postgres-username TEXT The username of the PostgreSQL user that is authorized
to create new databases.
--postgres-password TEXT The password of the PostgreSQL user that is authorized
to create new databases.
-I, --interactive / -n, --non-interactive
If set to `--non-interactive`, the command will never
prompt, such as for a sudo password. [default:
(--interactive)]
--help Show this message and exit.
.. _reference:command-line:verdi-process:
Expand Down Expand Up @@ -412,8 +416,11 @@ Below is a list with all available subcommands.
(Deprecated) Setup a new profile in a fully automated fashion.
Options:
-n, --non-interactive In non-interactive mode, the CLI never prompts but
simply uses default values for options that define one.
-I, --interactive / -n, --non-interactive
In interactive mode, the CLI will prompt for each
option. In non-interactive mode, the CLI never prompts
but simply uses default values for options that define
one. [default: (--interactive)]
--profile PROFILE The name of the new profile. [required]
--email EMAIL Email address associated with the data you generate. The
email address is exported along with the data, when
Expand Down Expand Up @@ -516,8 +523,11 @@ Below is a list with all available subcommands.
user has been created.
Options:
-n, --non-interactive In non-interactive mode, the CLI never prompts but
simply uses default values for options that define one.
-I, --interactive / -n, --non-interactive
In interactive mode, the CLI will prompt for each
option. In non-interactive mode, the CLI never prompts
but simply uses default values for options that define
one. [default: (--interactive)]
--profile PROFILE The name of the new profile. [required]
--email EMAIL Email address associated with the data you generate. The
email address is exported along with the data, when
Expand Down
26 changes: 16 additions & 10 deletions src/aiida/brokers/rabbitmq/defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,23 +29,29 @@
)


def detect_rabbitmq_config(**kwargs) -> dict[str, t.Any] | None:
def detect_rabbitmq_config(
protocol: str | None = None,
username: str | None = None,
password: str | None = None,
host: str | None = None,
port: int | None = None,
virtual_host: str | None = None,
heartbeat: int | None = None,
) -> dict[str, t.Any] | None:
"""Try to connect to a RabbitMQ server with the default connection parameters.
:returns: The connection parameters if the RabbitMQ server was successfully connected to, or ``None`` otherwise.
"""
from kiwipy.rmq.threadcomms import connect

connection_params = {
'protocol': kwargs.get('broker_protocol', os.getenv('AIIDA_BROKER_PROTOCOL', BROKER_DEFAULTS['protocol'])),
'username': kwargs.get('broker_username', os.getenv('AIIDA_BROKER_USERNAME', BROKER_DEFAULTS['username'])),
'password': kwargs.get('broker_password', os.getenv('AIIDA_BROKER_PASSWORD', BROKER_DEFAULTS['password'])),
'host': kwargs.get('broker_host', os.getenv('AIIDA_BROKER_HOST', BROKER_DEFAULTS['host'])),
'port': kwargs.get('broker_port', os.getenv('AIIDA_BROKER_PORT', BROKER_DEFAULTS['port'])),
'virtual_host': kwargs.get(
'broker_virtual_host', os.getenv('AIIDA_BROKER_VIRTUAL_HOST', BROKER_DEFAULTS['virtual_host'])
),
'heartbeat': kwargs.get('broker_heartbeat', os.getenv('AIIDA_BROKER_HEARTBEAT', BROKER_DEFAULTS['heartbeat'])),
'protocol': protocol or os.getenv('AIIDA_BROKER_PROTOCOL', BROKER_DEFAULTS['protocol']),
'username': username or os.getenv('AIIDA_BROKER_USERNAME', BROKER_DEFAULTS['username']),
'password': password or os.getenv('AIIDA_BROKER_PASSWORD', BROKER_DEFAULTS['password']),
'host': host or os.getenv('AIIDA_BROKER_HOST', BROKER_DEFAULTS['host']),
'port': port or os.getenv('AIIDA_BROKER_PORT', BROKER_DEFAULTS['port']),
'virtual_host': virtual_host or os.getenv('AIIDA_BROKER_VIRTUAL_HOST', BROKER_DEFAULTS['virtual_host']),
'heartbeat': heartbeat or os.getenv('AIIDA_BROKER_HEARTBEAT', BROKER_DEFAULTS['heartbeat']),
}

LOGGER.info(f'Attempting to connect to RabbitMQ with parameters: {connection_params}')
Expand Down
10 changes: 5 additions & 5 deletions src/aiida/cmdline/commands/cmd_code.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def verdi_code():
"""Setup and manage codes."""


def create_code(ctx: click.Context, cls, non_interactive: bool, **kwargs):
def create_code(ctx: click.Context, cls, interactive: bool, **kwargs):
"""Create a new `Code` instance."""
try:
instance = cls(**kwargs)
Expand Down Expand Up @@ -101,11 +101,11 @@ def set_code_builder(ctx, param, value):
@options_code.USE_DOUBLE_QUOTES()
@options_code.PREPEND_TEXT()
@options_code.APPEND_TEXT()
@options.NON_INTERACTIVE()
@options.INTERACTIVE()
@options.CONFIG_FILE()
@click.pass_context
@with_dbenv()
def setup_code(ctx, non_interactive, **kwargs):
def setup_code(ctx, interactive, **kwargs):
"""Setup a new code (use `verdi code create`)."""
from aiida.orm.utils.builders.code import CodeBuilder

Expand Down Expand Up @@ -173,11 +173,11 @@ def code_test(code):
@options_code.REL_PATH(contextual_default=partial(get_default, 'code_rel_path'))
@options_code.PREPEND_TEXT(contextual_default=partial(get_default, 'prepend_text'))
@options_code.APPEND_TEXT(contextual_default=partial(get_default, 'append_text'))
@options.NON_INTERACTIVE()
@options.INTERACTIVE()
@click.option('--hide-original', is_flag=True, default=False, help='Hide the code being copied.')
@click.pass_context
@with_dbenv()
def code_duplicate(ctx, code, non_interactive, **kwargs):
def code_duplicate(ctx, code, interactive, **kwargs):
"""Duplicate a code allowing to change some parameters."""
from aiida.common.exceptions import ValidationError
from aiida.orm.utils.builders.code import CodeBuilder
Expand Down
8 changes: 4 additions & 4 deletions src/aiida/cmdline/commands/cmd_computer.py
Original file line number Diff line number Diff line change
Expand Up @@ -285,11 +285,11 @@ def set_computer_builder(ctx, param, value):
@options_computer.USE_DOUBLE_QUOTES()
@options_computer.PREPEND_TEXT()
@options_computer.APPEND_TEXT()
@options.NON_INTERACTIVE()
@options.INTERACTIVE()
@options.CONFIG_FILE()
@click.pass_context
@with_dbenv()
def computer_setup(ctx, non_interactive, **kwargs):
def computer_setup(ctx, interactive, **kwargs):
"""Create a new computer."""
from aiida.orm.utils.builders.computer import ComputerBuilder

Expand Down Expand Up @@ -338,10 +338,10 @@ def computer_setup(ctx, non_interactive, **kwargs):
)
@options_computer.PREPEND_TEXT(contextual_default=partial(get_parameter_default, 'prepend_text'))
@options_computer.APPEND_TEXT(contextual_default=partial(get_parameter_default, 'append_text'))
@options.NON_INTERACTIVE()
@options.INTERACTIVE()
@click.pass_context
@with_dbenv()
def computer_duplicate(ctx, computer, non_interactive, **kwargs):
def computer_duplicate(ctx, computer, interactive, **kwargs):
"""Duplicate a computer allowing to change some parameters."""
from aiida.orm.utils.builders.computer import ComputerBuilder

Expand Down
10 changes: 5 additions & 5 deletions src/aiida/cmdline/commands/cmd_presto.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def detect_postgres_config(
postgres_port: int,
postgres_username: str,
postgres_password: str,
non_interactive: bool,
interactive: bool,
) -> dict[str, t.Any]:
"""."""
import secrets
Expand All @@ -62,7 +62,7 @@ def detect_postgres_config(
'user': postgres_username,
'password': postgres_password,
}
postgres = Postgres(interactive=not non_interactive, quiet=False, dbinfo=dbinfo)
postgres = Postgres(interactive=interactive, quiet=False, dbinfo=dbinfo)

if not postgres.is_connected:
echo.echo_critical(f'Failed to connect to the PostgreSQL server using parameters: {dbinfo}')
Expand Down Expand Up @@ -123,7 +123,7 @@ def detect_postgres_config(
required=False,
help='The password of the PostgreSQL user that is authorized to create new databases.',
)
@options.NON_INTERACTIVE(help='Never prompt, such as for sudo password.')
@options.INTERACTIVE(help='If set to `--non-interactive`, the command will never prompt, such as for a sudo password.')
@click.pass_context
def verdi_presto(
ctx,
Expand All @@ -134,7 +134,7 @@ def verdi_presto(
postgres_port,
postgres_username,
postgres_password,
non_interactive,
interactive,
):
"""Set up a new profile in a jiffy.
Expand Down Expand Up @@ -173,7 +173,7 @@ def verdi_presto(
'postgres_port': postgres_port,
'postgres_username': postgres_username,
'postgres_password': postgres_password,
'non_interactive': non_interactive,
'interactive': interactive,
}
storage_config: dict[str, t.Any] = detect_postgres_config(**postgres_config_kwargs) if use_postgres else {}
storage_backend = 'core.psql_dos' if storage_config else 'core.sqlite_dos'
Expand Down
30 changes: 17 additions & 13 deletions src/aiida/cmdline/commands/cmd_profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ def verdi_profile():


def command_create_profile(
ctx: click.Context, storage_cls, non_interactive: bool, profile: Profile, set_as_default: bool = True, **kwargs
ctx: click.Context, storage_cls, interactive: bool, profile: Profile, set_as_default: bool = True, **kwargs
):
"""Create a new profile, initialise its storage and create a default user.
:param ctx: The context of the CLI command.
:param storage_cls: The storage class obtained through loading the entry point from ``aiida.storage`` group.
:param non_interactive: Whether the command was invoked interactively or not.
:param interactive: Whether the command was invoked interactively or not.
:param profile: The profile instance. This is an empty ``Profile`` instance created by the command line argument
which currently only contains the selected profile name for the profile that is to be created.
:param set_as_default: Whether to set the created profile as the new default.
Expand Down Expand Up @@ -130,34 +130,38 @@ def profile_setup():

@verdi_profile.command('configure-rabbitmq') # type: ignore[arg-type]
@arguments.PROFILE(default=defaults.get_default_profile)
@options.INTERACTIVE(default=False, show_default='--non-interactive')
@options.FORCE()
@setup.SETUP_BROKER_PROTOCOL()
@setup.SETUP_BROKER_USERNAME()
@setup.SETUP_BROKER_PASSWORD()
@setup.SETUP_BROKER_HOST()
@setup.SETUP_BROKER_PORT()
@setup.SETUP_BROKER_VIRTUAL_HOST()
@options.INTERACTIVE()
@click.pass_context
def profile_configure_rabbitmq(ctx, profile, **kwargs):
def profile_configure_rabbitmq(ctx, profile, interactive, force, **kwargs):
"""Configure RabbitMQ for a profile.
Enable RabbitMQ for a profile that was created without a broker, or reconfigure existing connection details.
"""
from aiida.brokers.rabbitmq.defaults import detect_rabbitmq_config

profile.set_process_controller(name='core.rabbitmq', config=kwargs)
ctx.obj.config.update_profile(profile)
ctx.obj.config.store()
connection_params = {key.lstrip('broker_'): value for key, value in kwargs.items() if key.startswith('broker_')}

broker_config = detect_rabbitmq_config(**kwargs)
broker_config = detect_rabbitmq_config(**connection_params)

if broker_config is None:
connection_params = {key: value for key, value in kwargs.items() if key.startswith('broker_')}
echo.echo_warning(
f'RabbitMQ configured but unable to connect to RabbitMQ server with configuration: {connection_params}'
)
echo.echo_warning(f'Unable to connect to RabbitMQ server with configuration: {connection_params}')
if not force:
click.confirm('Do you want to continue with the provided configuration?', abort=True)
else:
echo.echo_success('Successfully connected to RabbitMQ server.')
echo.echo_success('Connected to RabbitMQ with the provided connection parameters')

profile.set_process_controller(name='core.rabbitmq', config=kwargs)
ctx.obj.config.update_profile(profile)
ctx.obj.config.store()

echo.echo_success(f'RabbitMQ configuration for `{profile.name}` updated to: {connection_params}')


@verdi_profile.command('list')
Expand Down
12 changes: 6 additions & 6 deletions src/aiida/cmdline/commands/cmd_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@


@verdi.command('setup', deprecated='Please use `verdi profile setup` instead.')
@options.NON_INTERACTIVE()
@options.INTERACTIVE()
@options_setup.SETUP_PROFILE()
@options_setup.SETUP_USER_EMAIL()
@options_setup.SETUP_USER_FIRST_NAME()
Expand All @@ -44,7 +44,7 @@
@click.pass_context
def setup(
ctx,
non_interactive,
interactive,
profile: Profile,
email,
first_name,
Expand Down Expand Up @@ -141,7 +141,7 @@ def setup(
deprecated='This command is deprecated. For a fully automated alternative, use `verdi presto --use-postgres` '
'instead. For full control, use `verdi profile setup core.psql_dos`.',
)
@options.NON_INTERACTIVE()
@options.INTERACTIVE()
# Cannot use `default` because that will fail validation of the `ProfileParamType` if the profile already exists and it
# will be validated before the prompt to choose another. The `contextual_default` however, will not trigger the
# validation but will populate the default in the prompt.
Expand Down Expand Up @@ -172,7 +172,7 @@ def setup(
@click.pass_context
def quicksetup(
ctx,
non_interactive,
interactive,
profile,
email,
first_name,
Expand Down Expand Up @@ -210,7 +210,7 @@ def quicksetup(
'password': su_db_password,
'database': su_db_name,
}
postgres = Postgres(interactive=not non_interactive, quiet=False, dbinfo=dbinfo_su)
postgres = Postgres(interactive=interactive, quiet=False, dbinfo=dbinfo_su)

if not postgres.is_connected:
echo.echo_critical('failed to determine the PostgreSQL setup')
Expand All @@ -231,7 +231,7 @@ def quicksetup(
# The contextual defaults or `verdi setup` are not being called when `invoking`, so we have to explicitly define
# them here, even though the `verdi setup` command would populate those when called from the command line.
setup_parameters = {
'non_interactive': non_interactive,
'interactive': interactive,
'profile': profile,
'email': email,
'first_name': first_name,
Expand Down
2 changes: 1 addition & 1 deletion src/aiida/cmdline/groups/dynamic.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ def create_options(self, entry_point: str) -> t.Callable:

def apply_options(func):
"""Decorate the command function with the appropriate options for the given entry point."""
func = options.NON_INTERACTIVE()(func)
func = options.INTERACTIVE()(func)
func = options.CONFIG_FILE()(func)

options_list = self.list_options(entry_point)
Expand Down
1 change: 1 addition & 0 deletions src/aiida/cmdline/params/options/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
'IDENTIFIER',
'INPUT_FORMAT',
'INPUT_PLUGIN',
'INTERACTIVE',
'LABEL',
'LIMIT',
'MultipleValueOption',
Expand Down
5 changes: 3 additions & 2 deletions src/aiida/cmdline/params/options/interactive.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,10 +167,11 @@ def get_default(self, ctx: click.Context, call: bool = True) -> t.Optional[t.Uni
def is_interactive(ctx: click.Context) -> bool:
"""Return whether the command is being run non-interactively.
This is the case if the ``non_interactive`` parameter in the context is set to ``True``.
This is the case if the ``interactive`` parameter in the context is set to ``True``.
:return: ``True`` if being run non-interactively, ``False`` otherwise.
:return: ``True`` if being run interactively, ``False`` otherwise.
"""
# This logic is left in place for backwards compatibility of the now deprecated `NON_INTERACTIVE` option.
if ctx.params.get('non_interactive', None) is not None:
return not ctx.params['non_interactive']

Expand Down
5 changes: 4 additions & 1 deletion src/aiida/cmdline/params/options/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -350,17 +350,20 @@ def set_log_level(_ctx, _param, value):
is_flag=True,
is_eager=True,
help='In non-interactive mode, the CLI never prompts but simply uses default values for options that define one.',
deprecated=('The `NON_INTERACTIVE` option is deprecated, use `INTERACTIVE` instead.', 3),
)

INTERACTIVE = OverridableOption(
'-I/-n',
'--interactive/--non-interactive',
is_flag=True,
is_eager=True,
default=True,
show_default='--interactive',
help=(
'In interactive mode, the CLI will prompt for each option. '
'In non-interactive mode, the CLI never prompts but simply uses default values for options that define one.'
),
show_default='--non-interactive',
)

DRY_RUN = OverridableOption('-n', '--dry-run', is_flag=True, help='Perform a dry run.')
Expand Down
Loading

0 comments on commit e87eb5c

Please sign in to comment.