Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Comment Support for Streamlit App Creation #1580

Merged
merged 7 commits into from
Sep 19, 2024
3 changes: 3 additions & 0 deletions src/snowflake/cli/_plugins/streamlit/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ def _create_streamlit(
if streamlit.title:
query.append(f"TITLE = '{streamlit.title}'")

if streamlit.comment:
query.append(f"COMMENT = '{streamlit.comment}'")

if streamlit.external_access_integrations:
query.append(streamlit.get_external_access_integrations_sql())

Expand Down
1 change: 1 addition & 0 deletions src/snowflake/cli/api/project/definition_conversion.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ def convert_streamlit_to_v2_data(streamlit: Streamlit) -> Dict[str, Any]:
"type": "streamlit",
"identifier": identifier,
"title": streamlit.title,
"comment": streamlit.comment,
"query_warehouse": streamlit.query_warehouse,
"main_file": str(streamlit.main_file),
"pages_dir": str(streamlit.pages_dir),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class StreamlitEntityModel(EntityModelBase, ExternalAccessBaseModel):
title: Optional[str] = Field(
title="Human-readable title for the Streamlit dashboard", default=None
)
comment: Optional[str] = Field(title="Comment for the Streamlit app", default=None)
sfc-gh-vmaleki marked this conversation as resolved.
Show resolved Hide resolved
query_warehouse: str = Field(
title="Snowflake warehouse to host the app", default=None
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,4 @@ class Streamlit(UpdatableModel, ObjectIdentifierModel(object_name="Streamlit")):
title: Optional[str] = Field(
title="Human-readable title for the Streamlit dashboard", default=None
)
comment: Optional[str] = Field(title="Comment for the Streamlit app", default=None)
1 change: 1 addition & 0 deletions tests/project/__snapshots__/test_config.ambr
Original file line number Diff line number Diff line change
Expand Up @@ -774,6 +774,7 @@
'utils/utils.py',
'extra_file.py',
]),
'comment': None,
'database': None,
'env_file': 'environment.yml',
'main_file': 'streamlit_app.py',
Expand Down
43 changes: 43 additions & 0 deletions tests/streamlit/test_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -911,3 +911,46 @@ def test_multiple_streamlit_raise_error_if_multiple_entities(

assert result.exit_code == 2, result.output
assert result.output == os_agnostic_snapshot


@mock.patch("snowflake.connector.connect")
def test_deploy_streamlit_with_comment_v2(
mock_connector, mock_cursor, runner, mock_ctx, project_directory
):
ctx = mock_ctx(
mock_cursor(
rows=[
{"SYSTEM$GET_SNOWSIGHT_HOST()": "https://snowsight.domain"},
{"REGIONLESS": "false"},
{"CURRENT_ACCOUNT_NAME()": "https://snowsight.domain"},
],
columns=["SYSTEM$GET_SNOWSIGHT_HOST()"],
)
)
mock_connector.return_value = ctx

with project_directory("example_streamlit_with_comment_v2"):
result = runner.invoke(["streamlit", "deploy", "--replace"])

root_path = f"@MockDatabase.MockSchema.streamlit/test_streamlit_deploy_snowcli"
assert result.exit_code == 0, result.output
assert ctx.get_queries() == [
f"describe streamlit IDENTIFIER('MockDatabase.MockSchema.test_streamlit_deploy_snowcli')",
"create stage if not exists IDENTIFIER('MockDatabase.MockSchema.streamlit')",
_put_query("streamlit_app.py", root_path),
_put_query("pages/*", f"{root_path}/pages"),
_put_query("environment.yml", root_path),
dedent(
f"""
CREATE OR REPLACE STREAMLIT IDENTIFIER('MockDatabase.MockSchema.test_streamlit_deploy_snowcli')
ROOT_LOCATION = '@MockDatabase.MockSchema.streamlit/test_streamlit_deploy_snowcli'
MAIN_FILE = 'streamlit_app.py'
QUERY_WAREHOUSE = xsmall
TITLE = 'My Streamlit App with Comment'
COMMENT = 'This is a test comment'
"""
).strip(),
"select system$get_snowsight_host()",
REGIONLESS_QUERY,
"select current_account_name()",
]
39 changes: 39 additions & 0 deletions tests/streamlit/test_streamlit_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,42 @@ def test_deploy_streamlit_with_api_integrations(
secrets=('my_secret'=SecretOfTheSecrets, 'other'=other_secret)"""
)
)


@mock.patch("snowflake.cli._plugins.streamlit.manager.StageManager")
@mock.patch("snowflake.cli._plugins.streamlit.manager.StreamlitManager.get_url")
@mock.patch("snowflake.cli._plugins.streamlit.manager.StreamlitManager._execute_query")
@mock_streamlit_exists
def test_deploy_streamlit_with_comment(
mock_execute_query, _, mock_stage_manager, temp_dir
):
mock_stage_manager().get_standard_stage_prefix.return_value = "stage_root"

main_file = Path(temp_dir) / "main.py"
main_file.touch()

st = StreamlitEntityModel(
type="streamlit",
identifier="my_streamlit_app",
title="MyStreamlit",
query_warehouse="My_WH",
main_file=str(main_file),
artifacts=[main_file],
comment="This is a test comment",
)

StreamlitManager(MagicMock(database="DB", schema="SH")).deploy(
streamlit=st, replace=False
)

mock_execute_query.assert_called_once_with(
dedent(
f"""\
CREATE STREAMLIT IDENTIFIER('DB.SH.my_streamlit_app')
ROOT_LOCATION = 'stage_root'
MAIN_FILE = '{main_file}'
QUERY_WAREHOUSE = My_WH
TITLE = 'MyStreamlit'
COMMENT = 'This is a test comment'"""
)
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
name: sf_env
channels:
- snowflake
dependencies:
- pandas
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import streamlit as st

st.title("Example page")
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
definition_version: 2
entities:
my_streamlit:
type: "streamlit"
identifier: test_streamlit_deploy_snowcli
title: "My Streamlit App with Comment"
stage: streamlit
query_warehouse: xsmall
main_file: streamlit_app.py
artifacts:
- streamlit_app.py
- pages/
- environment.yml
comment: "This is a test comment"
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import streamlit as st

st.title("Example streamlit app")
Loading