Skip to content

Commit 48b6a2f

Browse files
SNOW-2206349 Fix Streamlit Entity Grants
1 parent 2961950 commit 48b6a2f

File tree

4 files changed

+94
-0
lines changed

4 files changed

+94
-0
lines changed

RELEASE-NOTES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
## New additions
2222

2323
## Fixes and improvements
24+
* Grant privileges defined in `snowflake.yml` after deploying Streamlit
2425

2526

2627
# v3.12.0

src/snowflake/cli/_plugins/streamlit/streamlit_entity.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from snowflake.cli._plugins.connection.util import make_snowsight_url
77
from snowflake.cli._plugins.nativeapp.artifacts import build_bundle
88
from snowflake.cli._plugins.stage.manager import StageManager
9+
from snowflake.cli._plugins.streamlit.manager import StreamlitManager
910
from snowflake.cli._plugins.streamlit.streamlit_entity_model import (
1011
StreamlitEntityModel,
1112
)
@@ -132,6 +133,8 @@ def deploy(
132133
self.get_deploy_sql(replace=replace, from_stage_name=stage_root)
133134
)
134135

136+
StreamlitManager().grant_privileges(self.model)
137+
135138
return self.perform(EntityActions.GET_URL, action_context, *args, **kwargs)
136139

137140
def describe(self) -> SnowflakeCursor:
@@ -256,3 +259,5 @@ def _deploy_experimental(
256259
print_diff=True,
257260
force_overwrite=True, # files copied to streamlit vstage need to be overwritten
258261
)
262+
263+
StreamlitManager().grant_privileges(self.model)

tests_integration/test_streamlit.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import uuid
2+
13
import pytest
24

35
from tests_integration.testing_utils import FlowTestSetup
@@ -132,3 +134,65 @@ def _test_setup(
132134
@pytest.fixture
133135
def _streamlit_test_steps(_test_setup):
134136
return StreamlitTestSteps(_test_setup)
137+
138+
139+
@pytest.mark.integration
140+
def test_streamlit_grants_flow(
141+
_streamlit_test_steps,
142+
project_directory,
143+
snowflake_session,
144+
alter_snowflake_yml,
145+
):
146+
"""Test that streamlit grants are properly applied during deployment."""
147+
test_role = f"snowcli_streamlit_grants_test_{uuid.uuid4().hex[:8]}"
148+
entity_id = "app_1"
149+
150+
_streamlit_test_steps.create_test_role(test_role)
151+
152+
with project_directory("streamlit_v2"):
153+
alter_snowflake_yml(
154+
"snowflake.yml",
155+
"entities.app_1.grants",
156+
[{"privilege": "USAGE", "role": test_role}],
157+
)
158+
159+
_streamlit_test_steps.deploy_with_entity_id_specified_should_succeed(
160+
entity_id, snowflake_session, experimental=False
161+
)
162+
163+
_streamlit_test_steps.verify_grants_applied(entity_id, test_role)
164+
165+
_streamlit_test_steps.drop_should_succeed(entity_id, snowflake_session)
166+
167+
_streamlit_test_steps.cleanup_test_role(test_role)
168+
169+
170+
@pytest.mark.integration
171+
def test_streamlit_grants_experimental_flow(
172+
_streamlit_test_steps,
173+
project_directory,
174+
snowflake_session,
175+
alter_snowflake_yml,
176+
):
177+
"""Test that streamlit grants are properly applied during experimental deployment."""
178+
test_role = f"snowcli_streamlit_grants_exp_test_{uuid.uuid4().hex[:8]}"
179+
entity_id = "app_1"
180+
181+
_streamlit_test_steps.create_test_role(test_role)
182+
183+
with project_directory("streamlit_v2"):
184+
alter_snowflake_yml(
185+
"snowflake.yml",
186+
"entities.app_1.grants",
187+
[{"privilege": "USAGE", "role": test_role}],
188+
)
189+
190+
_streamlit_test_steps.deploy_with_entity_id_specified_should_succeed(
191+
entity_id, snowflake_session, experimental=True
192+
)
193+
194+
_streamlit_test_steps.verify_grants_applied(entity_id, test_role)
195+
196+
_streamlit_test_steps.drop_should_succeed(entity_id, snowflake_session)
197+
198+
_streamlit_test_steps.cleanup_test_role(test_role)

tests_integration/testing_utils/streamlit_utils.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,30 @@ def assert_proper_url_is_returned(
183183
assert message.startswith("Streamlit successfully deployed and available under")
184184
assert message.endswith(create_expected_url_suffix(entity_id, session))
185185

186+
def create_test_role(self, role_name: str):
187+
self.setup.sql_test_helper.execute_single_sql(
188+
f"set user = (select current_user()); "
189+
f"create role {role_name}; "
190+
f"grant role {role_name} to user IDENTIFIER($USER)"
191+
)
192+
193+
def cleanup_test_role(self, role_name: str):
194+
self.setup.sql_test_helper.execute_single_sql(
195+
f"DROP ROLE IF EXISTS {role_name}"
196+
)
197+
198+
def verify_grants_applied(self, entity_id: str, test_role: str):
199+
try:
200+
self.setup.sql_test_helper.execute_single_sql(f"USE ROLE {test_role}")
201+
streamlits_with_role = self.setup.sql_test_helper.execute_single_sql(
202+
f"SHOW STREAMLITS LIKE '{entity_id}'"
203+
)
204+
assert (
205+
len(streamlits_with_role) == 1
206+
), f"Role {test_role} should have USAGE access to the streamlit"
207+
finally:
208+
self.setup.sql_test_helper.execute_single_sql("USE ROLE ACCOUNTADMIN")
209+
186210

187211
def create_expected_url_suffix(entity_id: str, session: SnowflakeConnection):
188212
return f".snowflake.com/SFENGINEERING/{get_account(session)}/#/streamlit-apps/{session.database.upper()}.{session.schema.upper()}.{entity_id.upper()}"

0 commit comments

Comments
 (0)