diff --git a/src/snowflake/cli/api/commands/flags.py b/src/snowflake/cli/api/commands/flags.py index e15eed2b4c..af61d9103f 100644 --- a/src/snowflake/cli/api/commands/flags.py +++ b/src/snowflake/cli/api/commands/flags.py @@ -389,11 +389,18 @@ def _callback(project_path: Optional[str]): cli_context_manager.set_project_root(project_root) return project_definition + if project_name == "native_app": + project_name_help = "Snowflake Native App" + elif project_name == "streamlit": + project_name_help = "Streamlit app" + else: + project_name_help = project_name.replace("_", " ").capitalize() + return typer.Option( None, "-p", "--project", - help=f"Path where the {'Snowflake Native App' if project_name == 'native_app' else project_name.replace('_', ' ').capitalize()} project resides. " + help=f"Path where the {project_name_help} project resides. " f"Defaults to current working directory.", callback=_callback, show_default=False, diff --git a/src/snowflake/cli/api/commands/project_initialisation.py b/src/snowflake/cli/api/commands/project_initialisation.py index a1802cd157..b851fe31b2 100644 --- a/src/snowflake/cli/api/commands/project_initialisation.py +++ b/src/snowflake/cli/api/commands/project_initialisation.py @@ -1,5 +1,7 @@ from __future__ import annotations +from typing import Optional + from snowflake.cli.api.commands.snow_typer import SnowTyper from snowflake.cli.api.constants import TEMPLATES_PATH from snowflake.cli.api.output.types import CommandResult, MessageResult @@ -13,21 +15,29 @@ def _create_project_template(template_name: str, project_directory: str): ) -def add_init_command(app: SnowTyper, project_type: str, template: str): +def add_init_command( + app: SnowTyper, project_type: str, template: str, help_message: Optional[str] = None +): @app.command() def init( project_name: str = Argument( f"example_{project_type.lower()}", - help=f"Name of the {project_type} project you want to create.", + help=help_message + if help_message is not None + else f"Name of the {project_type} project you want to create.", ), **options, ) -> CommandResult: _create_project_template(template, project_directory=project_name) return MessageResult(f"Initialized the new project in {project_name}/") + project_type_doc = ( + project_type if project_type.lower() != "streamlit" else "Streamlit app" + ) + init.__doc__ = ( f"Initializes this directory with a sample set " - f"of files for creating a {project_type} project." + f"of files for creating a {project_type_doc} project." ) return init diff --git a/src/snowflake/cli/api/project/schemas/streamlit/streamlit.py b/src/snowflake/cli/api/project/schemas/streamlit/streamlit.py index ce6b5e08c9..af113e27b6 100644 --- a/src/snowflake/cli/api/project/schemas/streamlit/streamlit.py +++ b/src/snowflake/cli/api/project/schemas/streamlit/streamlit.py @@ -15,7 +15,7 @@ class Streamlit(UpdatableModel): title="Snowflake warehouse to host the app", default="streamlit" ) main_file: Optional[str] = Field( - title="Entrypoint file of the streamlit app", default="streamlit_app.py" + title="Entrypoint file of the Streamlit app", default="streamlit_app.py" ) env_file: Optional[str] = Field( title="File defining additional configurations for the app, such as external dependencies", diff --git a/src/snowflake/cli/plugins/streamlit/commands.py b/src/snowflake/cli/plugins/streamlit/commands.py index 3f018ed8d2..05bdeb3e3e 100644 --- a/src/snowflake/cli/plugins/streamlit/commands.py +++ b/src/snowflake/cli/plugins/streamlit/commands.py @@ -22,7 +22,7 @@ app = SnowTyper( name="streamlit", - help="Manages Streamlit in Snowflake.", + help="Manages a Streamlit app in Snowflake.", ) log = logging.getLogger(__name__) @@ -30,18 +30,30 @@ StageNameOption: str = typer.Option( "streamlit", "--stage", - help="Stage name where Streamlit files will be uploaded.", + help="Name of the stage where you want to upload Streamlit app files.", +) + +OpenOption = typer.Option( + False, + "--open", + help="Whether to open the Streamlit app in a browser.", + is_flag=True, ) -add_init_command(app, project_type="Streamlit", template="default_streamlit") +add_init_command( + app, + project_type="Streamlit", + template="default_streamlit", + help_message="Name of the Streamlit app project directory you want to create. Defaults to `example_streamlit`.", +) @app.command("share", requires_connection=True) def streamlit_share( - name: str = typer.Argument(..., help="Name of streamlit to share."), + name: str = typer.Argument(..., help="Name of the Streamlit app to share."), to_role: str = typer.Argument( - ..., help="Role that streamlit should be shared with." + ..., help="Role with which to share the Streamlit app." ), **options, ) -> CommandResult: @@ -71,16 +83,16 @@ def _check_file_exists_if_not_default(ctx: click.Context, value): @with_project_definition("streamlit") @with_experimental_behaviour() def streamlit_deploy( - replace: bool = ReplaceOption(help="Replace the Streamlit if it already exists."), - open_: bool = typer.Option( - False, "--open", help="Whether to open Streamlit in a browser.", is_flag=True + replace: bool = ReplaceOption( + help="Replace the Streamlit app if it already exists." ), + open_: bool = OpenOption, **options, ) -> CommandResult: """ - Deploys a Streamlit dashboard defined in project definition file (snowflake.yml). By default, the command will - upload environment.yml and pages/ folder if present. If stage name is not specified then 'streamlit' stage - will be used. If stage does not exist it will be created by this command. + Deploys a Streamlit app defined in the project definition file (snowflake.yml). By default, the command uploads + environment.yml and any other pages or folders, if present. If you don’t specify a stage name, the `streamlit` + stage is used. If the specified stage does not exist, the command creates it. """ streamlit: Streamlit = cli_context.project_definition if not streamlit: @@ -119,12 +131,10 @@ def streamlit_deploy( @app.command("get-url", requires_connection=True) def get_url( name: str = typer.Argument(..., help="Name of the Streamlit app."), - open_: bool = typer.Option( - False, "--open", help="Whether to open Streamlit in a browser.", is_flag=True - ), + open_: bool = OpenOption, **options, ): - """Returns url to provided streamlit app""" + """Returns a URL to the specified Streamlit app""" url = StreamlitManager().get_url(streamlit_name=name) if open_: typer.launch(url) diff --git a/tests/__snapshots__/test_help_messages.ambr b/tests/__snapshots__/test_help_messages.ambr index 019ea1efab..a7b99913d5 100644 --- a/tests/__snapshots__/test_help_messages.ambr +++ b/tests/__snapshots__/test_help_messages.ambr @@ -22,7 +22,7 @@ │ spcs Manages Snowpark Container Services compute pools, services, │ │ image registries, and image repositories. │ │ sql Executes Snowflake query. │ - │ streamlit Manages Streamlit in Snowflake. │ + │ streamlit Manages a Streamlit app in Snowflake. │ ╰──────────────────────────────────────────────────────────────────────────────╯ @@ -3943,17 +3943,17 @@ Usage: default streamlit deploy [OPTIONS] - Deploys a Streamlit dashboard defined in project definition file - (snowflake.yml). By default, the command will upload environment.yml and - pages/ folder if present. If stage name is not specified then 'streamlit' - stage will be used. If stage does not exist it will be created by this - command. + Deploys a Streamlit app defined in the project definition file + (snowflake.yml). By default, the command uploads environment.yml and any other + pages or folders, if present. If you don’t specify a stage name, the + `streamlit` stage is used. If the specified stage does not exist, the command + creates it. ╭─ Options ────────────────────────────────────────────────────────────────────╮ - │ --replace Replace the Streamlit if it already exists. │ - │ --open Whether to open Streamlit in a browser. │ - │ --project -p TEXT Path where the Streamlit project resides. Defaults │ - │ to current working directory. │ + │ --replace Replace the Streamlit app if it already exists. │ + │ --open Whether to open the Streamlit app in a browser. │ + │ --project -p TEXT Path where the Streamlit app project resides. │ + │ Defaults to current working directory. │ │ --help -h Show this message and exit. │ ╰──────────────────────────────────────────────────────────────────────────────╯ ╭─ Connection configuration ───────────────────────────────────────────────────╮ @@ -4011,13 +4011,13 @@ Usage: default streamlit get-url [OPTIONS] NAME - Returns url to provided streamlit app + Returns a URL to the specified Streamlit app ╭─ Arguments ──────────────────────────────────────────────────────────────────╮ │ * name TEXT Name of the Streamlit app. [default: None] [required] │ ╰──────────────────────────────────────────────────────────────────────────────╯ ╭─ Options ────────────────────────────────────────────────────────────────────╮ - │ --open Whether to open Streamlit in a browser. │ + │ --open Whether to open the Streamlit app in a browser. │ │ --help -h Show this message and exit. │ ╰──────────────────────────────────────────────────────────────────────────────╯ ╭─ Connection configuration ───────────────────────────────────────────────────╮ @@ -4076,11 +4076,12 @@ Usage: default streamlit init [OPTIONS] [PROJECT_NAME] Initializes this directory with a sample set of files for creating a Streamlit - project. + app project. ╭─ Arguments ──────────────────────────────────────────────────────────────────╮ - │ project_name [PROJECT_NAME] Name of the Streamlit project you want │ - │ to create. │ + │ project_name [PROJECT_NAME] Name of the Streamlit app project │ + │ directory you want to create. Defaults │ + │ to `example_streamlit`. │ │ [default: example_streamlit] │ ╰──────────────────────────────────────────────────────────────────────────────╯ ╭─ Options ────────────────────────────────────────────────────────────────────╮ @@ -4108,9 +4109,9 @@ Shares a Streamlit app with another role. ╭─ Arguments ──────────────────────────────────────────────────────────────────╮ - │ * name TEXT Name of streamlit to share. [default: None] │ + │ * name TEXT Name of the Streamlit app to share. [default: None] │ │ [required] │ - │ * to_role TEXT Role that streamlit should be shared with. │ + │ * to_role TEXT Role with which to share the Streamlit app. │ │ [default: None] │ │ [required] │ ╰──────────────────────────────────────────────────────────────────────────────╯ @@ -4172,20 +4173,20 @@ Usage: default streamlit [OPTIONS] COMMAND [ARGS]... - Manages Streamlit in Snowflake. + Manages a Streamlit app in Snowflake. ╭─ Options ────────────────────────────────────────────────────────────────────╮ │ --help -h Show this message and exit. │ ╰──────────────────────────────────────────────────────────────────────────────╯ ╭─ Commands ───────────────────────────────────────────────────────────────────╮ - │ deploy Deploys a Streamlit dashboard defined in project definition file │ - │ (snowflake.yml). By default, the command will upload │ - │ environment.yml and pages/ folder if present. If stage name is not │ - │ specified then 'streamlit' stage will be used. If stage does not │ - │ exist it will be created by this command. │ - │ get-url Returns url to provided streamlit app │ + │ deploy Deploys a Streamlit app defined in the project definition file │ + │ (snowflake.yml). By default, the command uploads environment.yml │ + │ and any other pages or folders, if present. If you don’t specify a │ + │ stage name, the `streamlit` stage is used. If the specified stage │ + │ does not exist, the command creates it. │ + │ get-url Returns a URL to the specified Streamlit app │ │ init Initializes this directory with a sample set of files for creating │ - │ a Streamlit project. │ + │ a Streamlit app project. │ │ share Shares a Streamlit app with another role. │ ╰──────────────────────────────────────────────────────────────────────────────╯ diff --git a/tests/test_cli.py b/tests/test_cli.py index ece4dff476..baa404bc29 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -14,7 +14,7 @@ def test_global(runner): [ ("object", "Manages Snowflake objects"), ("snowpark", "Manages procedures and functions."), - ("streamlit", " Manages Streamlit in Snowflake."), + ("streamlit", " Manages a Streamlit app in Snowflake."), ], ) def test_namespace(namespace, expected, runner): diff --git a/tests/test_command_registration.py b/tests/test_command_registration.py index 6a9666418c..c7a0c54707 100644 --- a/tests/test_command_registration.py +++ b/tests/test_command_registration.py @@ -15,7 +15,7 @@ def test_builtin_plugins_registration(runner): result = runner.invoke(["-h"]) assert result.exit_code == 0 assert result.output.count("Manages connections to Snowflake") == 1 - assert result.output.count("Manages Streamlit in Snowflake") == 1 + assert result.output.count("Manages a Streamlit app in Snowflake") == 1 assert result.output.count("Executes Snowflake query") == 1 @@ -23,7 +23,7 @@ def test_multiple_use_of_test_runner(runner): def assert_result_is_correct(result): assert result.exit_code == 0 assert result.output.count("Manages connections to Snowflake") == 1 - assert result.output.count("Manages Streamlit in Snowflake") == 1 + assert result.output.count("Manages a Streamlit app in Snowflake") == 1 assert result.output.count("Manages Snowflake objects") == 1 assert result.output.count("Executes Snowflake query") == 1 @@ -75,7 +75,7 @@ def test_exception_handling_if_single_command_has_callback( result = runner.invoke(["-h"]) assert result.output.count("Manages connections to Snowflake") == 0 - assert result.output.count("Manages Streamlit in Snowflake") == 1 + assert result.output.count("Manages a Streamlit app in Snowflake") == 1 @mock.patch("snowflake.cli.plugins.connection.plugin_spec.command_spec") @@ -93,7 +93,7 @@ def test_exception_handling_if_single_command_has_multiple_commands( result = runner.invoke(["-h"]) assert result.output.count("Manages connections to Snowflake") == 0 - assert result.output.count("Manages Streamlit in Snowflake") == 1 + assert result.output.count("Manages a Streamlit app in Snowflake") == 1 @mock.patch( @@ -119,7 +119,7 @@ def test_conflicting_command_plugin_paths_handling( result = runner.invoke(["-h"]) assert result.exit_code == 0 assert result.output.count("Manages connections to Snowflake") == 0 - assert result.output.count("Manages Streamlit in Snowflake") == 1 + assert result.output.count("Manages a Streamlit app in Snowflake") == 1 @mock.patch("snowflake.cli.plugins.streamlit.plugin_spec.command_spec") @@ -155,7 +155,7 @@ def test_not_existing_command_group_handling(connection_command_spec_mock, runne assert result.exit_code == 0 assert result.output.count("xyz123") == 0 assert result.output.count("Manages connections to Snowflake") == 0 - assert result.output.count("Manages Streamlit in Snowflake") == 1 + assert result.output.count("Manages a Streamlit app in Snowflake") == 1 @mock.patch("snowflake.cli.plugins.connection.plugin_spec.command_spec") @@ -165,7 +165,7 @@ def test_broken_command_spec_handling(connection_command_spec_mock, runner): result = runner.invoke(["-h"]) assert result.exit_code == 0 assert result.output.count("Manages connections to Snowflake") == 0 - assert result.output.count("Manages Streamlit in Snowflake") == 1 + assert result.output.count("Manages a Streamlit app in Snowflake") == 1 @mock.patch( @@ -177,7 +177,7 @@ def test_not_existing_external_entrypoint_handling(enabled_plugin_names_mock, ru result = runner.invoke(["-h"]) assert result.exit_code == 0 assert result.output.count("Manages connections to Snowflake") == 1 - assert result.output.count("Manages Streamlit in Snowflake") == 1 + assert result.output.count("Manages a Streamlit app in Snowflake") == 1 @mock.patch("pluggy.PluginManager.load_setuptools_entrypoints") @@ -193,4 +193,4 @@ def test_broken_external_entrypoint_handling( result = runner.invoke(["-h"]) assert result.exit_code == 0 assert result.output.count("Manages connections to Snowflake") == 1 - assert result.output.count("Manages Streamlit in Snowflake") == 1 + assert result.output.count("Manages a Streamlit app in Snowflake") == 1 diff --git a/tests_e2e/__snapshots__/test_installation.ambr b/tests_e2e/__snapshots__/test_installation.ambr index 3c091298da..984c13796a 100644 --- a/tests_e2e/__snapshots__/test_installation.ambr +++ b/tests_e2e/__snapshots__/test_installation.ambr @@ -32,7 +32,7 @@ │ spcs Manages Snowpark Container Services compute pools, services, │ │ image registries, and image repositories. │ │ sql Executes Snowflake query. │ - │ streamlit Manages Streamlit in Snowflake. │ + │ streamlit Manages a Streamlit app in Snowflake. │ ╰──────────────────────────────────────────────────────────────────────────────╯