Skip to content

Commit 5abff9b

Browse files
Snow 2097308 fix certificate issue on qa (#2322)
* remove snowflake.core from streamlit * fix tests
1 parent 834bf96 commit 5abff9b

File tree

7 files changed

+167
-176
lines changed

7 files changed

+167
-176
lines changed

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

Lines changed: 19 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,6 @@ def deploy(
9999
f"Streamlit {self.model.fqn.sql_identifier} already exists. Use 'replace' option to overwrite."
100100
)
101101

102-
console.step(f"Creating stage {self.model.stage} if not exists")
103-
stage = self._create_stage_if_not_exists()
104-
105102
if (
106103
experimental
107104
or GlobalFeatureFlag.ENABLE_STREAMLIT_VERSIONED_STAGE.is_enabled()
@@ -115,23 +112,20 @@ def deploy(
115112
name = (
116113
self.model.identifier.name
117114
if isinstance(self.model.identifier, Identifier)
118-
else self.model.identifier
115+
else self.model.identifier or self.entity_id
119116
)
120117
stage_root = StageManager.get_standard_stage_prefix(
121118
f"{FQN.from_string(self.model.stage).using_connection(self._conn)}/{name}"
122119
)
123-
if prune:
124-
sync_deploy_root_with_stage(
125-
console=self._workspace_ctx.console,
126-
deploy_root=bundle_map.deploy_root(),
127-
bundle_map=bundle_map,
128-
prune=prune,
129-
recursive=True,
130-
stage_path=StageManager().stage_path_parts_from_str(stage_root),
131-
print_diff=True,
132-
)
133-
else:
134-
self._upload_files_to_stage(stage, bundle_map, None)
120+
sync_deploy_root_with_stage(
121+
console=self._workspace_ctx.console,
122+
deploy_root=bundle_map.deploy_root(),
123+
bundle_map=bundle_map,
124+
prune=prune,
125+
recursive=True,
126+
stage_path=StageManager().stage_path_parts_from_str(stage_root),
127+
print_diff=True,
128+
)
135129

136130
console.step(f"Creating Streamlit object {self.model.fqn.sql_identifier}")
137131

@@ -266,17 +260,12 @@ def _deploy_experimental(
266260
else:
267261
stage_root = f"{embeded_stage_name}/default_checkout"
268262

269-
stage_resource = self._create_stage_if_not_exists(embeded_stage_name)
270-
271-
if prune:
272-
sync_deploy_root_with_stage(
273-
console=self._workspace_ctx.console,
274-
deploy_root=bundle_map.deploy_root(),
275-
bundle_map=bundle_map,
276-
prune=prune,
277-
recursive=True,
278-
stage_path=StageManager().stage_path_parts_from_str(stage_root),
279-
print_diff=True,
280-
)
281-
else:
282-
self._upload_files_to_stage(stage_resource, bundle_map)
263+
sync_deploy_root_with_stage(
264+
console=self._workspace_ctx.console,
265+
deploy_root=bundle_map.deploy_root(),
266+
bundle_map=bundle_map,
267+
prune=prune,
268+
recursive=True,
269+
stage_path=StageManager().stage_path_parts_from_str(stage_root),
270+
print_diff=True,
271+
)

src/snowflake/cli/api/entities/common.py

Lines changed: 0 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,13 @@
44
from typing import Generic, List, Optional, Type, TypeVar, get_args
55

66
from snowflake.cli._plugins.workspace.context import ActionContext, WorkspaceContext
7-
from snowflake.cli.api.artifacts.bundle_map import BundleMap
87
from snowflake.cli.api.cli_global_context import get_cli_context, span
98
from snowflake.cli.api.entities.resolver import Dependency, DependencyResolver
109
from snowflake.cli.api.entities.utils import EntityActions, get_sql_executor
1110
from snowflake.cli.api.identifiers import FQN
1211
from snowflake.cli.api.sql_execution import SqlExecutor
13-
from snowflake.cli.api.utils.path_utils import change_directory
14-
from snowflake.cli.api.utils.python_api_utils import StageEncryptionType
1512
from snowflake.connector import SnowflakeConnection
1613
from snowflake.connector.cursor import SnowflakeCursor
17-
from snowflake.core import CreateMode
18-
from snowflake.core.stage import Stage, StageEncryption, StageResource
1914

2015
T = TypeVar("T")
2116

@@ -129,13 +124,6 @@ def snow_api_root(self) -> Optional[object]:
129124
raise ValueError("snow_api_root is not set")
130125
return root
131126

132-
@property
133-
def stage_object(self) -> "StageResource":
134-
if self._stage_object is None:
135-
self._stage_object = self._create_stage_if_not_exists()
136-
137-
return self._stage_object
138-
139127
@property
140128
def model(self) -> T:
141129
return self._entity_model
@@ -152,53 +140,13 @@ def get_describe_sql(self) -> str:
152140
def get_drop_sql(self) -> str:
153141
return f"DROP {self.model.type.upper()} {self.identifier};" # type: ignore[attr-defined]
154142

155-
def _create_stage_if_not_exists(
156-
self, stage_name: Optional[str] = None
157-
) -> StageResource:
158-
if stage_name is None:
159-
stage_name = self.model.stage # type: ignore[attr-defined]
160-
161-
stage_collection = (
162-
self.snow_api_root.databases[self.database].schemas[self.schema].stages # type: ignore[attr-defined]
163-
)
164-
stage_object = Stage(
165-
name=stage_name,
166-
encryption=StageEncryption(type=StageEncryptionType.SNOWFLAKE_SSE.value),
167-
)
168-
169-
return stage_collection.create(stage_object, mode=CreateMode.if_not_exists)
170-
171143
def _get_identifier(
172144
self, schema: Optional[str] = None, database: Optional[str] = None
173145
) -> str:
174146
schema_to_use = schema or self._entity_model.fqn.schema or self._conn.schema # type: ignore
175147
db_to_use = database or self._entity_model.fqn.database or self._conn.database # type: ignore
176148
return f"{self._entity_model.fqn.set_schema(schema_to_use).set_database(db_to_use).sql_identifier}" # type: ignore
177149

178-
def _upload_files_to_stage(
179-
self,
180-
stage: StageResource,
181-
bundle_map: BundleMap,
182-
stage_root: Optional[str] = None,
183-
) -> None:
184-
with change_directory(self.root):
185-
for src, dest in bundle_map.all_mappings(
186-
absolute=True, expand_directories=True
187-
):
188-
if src.is_file():
189-
upload_dst = (
190-
f"{stage_root}/{dest.relative_to(self.root)}"
191-
if stage_root
192-
else f"/{self.fqn.name}/{get_parent_path_for_stage_deployment(dest.relative_to(bundle_map.deploy_root()))}"
193-
)
194-
195-
stage.put(
196-
local_file_name=src.relative_to(self.root),
197-
stage_location=upload_dst,
198-
overwrite=True,
199-
auto_compress=False,
200-
)
201-
202150
def get_from_fqn_or_conn(self, attribute_name: str) -> str:
203151
attribute = getattr(self.fqn, attribute_name, None) or getattr(
204152
self._conn, attribute_name, None

tests/conftest.py

Lines changed: 37 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -334,39 +334,41 @@ def execute_stream(self, query: StringIO, **kwargs):
334334
return self.execute_string(query.read(), **kwargs)
335335

336336

337-
@pytest.fixture
338-
def mock_cursor():
339-
class MockResultMetadata(NamedTuple):
340-
name: str
337+
class MockResultMetadata(NamedTuple):
338+
name: str
339+
340+
341+
class MockCursor(SnowflakeCursor):
342+
def __init__(self, rows: List[Union[tuple, dict]], columns: List[str]):
343+
super().__init__(mock.Mock())
344+
self._rows = rows
345+
self._columns = [MockResultMetadata(c) for c in columns]
346+
self.query = "SELECT A MOCK QUERY"
341347

342-
class _MockCursor(SnowflakeCursor):
343-
def __init__(self, rows: List[Union[tuple, dict]], columns: List[str]):
344-
super().__init__(mock.Mock())
345-
self._rows = rows
346-
self._columns = [MockResultMetadata(c) for c in columns]
347-
self.query = "SELECT A MOCK QUERY"
348+
def fetchone(self):
349+
if self._rows:
350+
return self._rows.pop(0)
351+
return None
348352

349-
def fetchone(self):
350-
if self._rows:
351-
return self._rows.pop(0)
352-
return None
353+
def fetchall(self):
354+
return self._rows
353355

354-
def fetchall(self):
355-
return self._rows
356+
@property
357+
def rowcount(self):
358+
return len(self._rows)
356359

357-
@property
358-
def rowcount(self):
359-
return len(self._rows)
360+
@property
361+
def description(self):
362+
yield from self._columns
360363

361-
@property
362-
def description(self):
363-
yield from self._columns
364+
@classmethod
365+
def from_input(cls, rows, columns):
366+
return cls(rows, columns)
364367

365-
@classmethod
366-
def from_input(cls, rows, columns):
367-
return cls(rows, columns)
368368

369-
return _MockCursor.from_input
369+
@pytest.fixture
370+
def mock_cursor():
371+
return MockCursor.from_input
370372

371373

372374
@pytest.fixture
@@ -512,12 +514,15 @@ def native_app_project_instance():
512514

513515
@pytest.fixture
514516
def enable_snowpark_glob_support_feature_flag():
515-
with mock.patch(
516-
f"snowflake.cli.api.feature_flags.FeatureFlag.ENABLE_SNOWPARK_GLOB_SUPPORT.is_enabled",
517-
return_value=True,
518-
), mock.patch(
519-
f"snowflake.cli.api.feature_flags.FeatureFlag.ENABLE_SNOWPARK_GLOB_SUPPORT.is_disabled",
520-
return_value=False,
517+
with (
518+
mock.patch(
519+
f"snowflake.cli.api.feature_flags.FeatureFlag.ENABLE_SNOWPARK_GLOB_SUPPORT.is_enabled",
520+
return_value=True,
521+
),
522+
mock.patch(
523+
f"snowflake.cli.api.feature_flags.FeatureFlag.ENABLE_SNOWPARK_GLOB_SUPPORT.is_disabled",
524+
return_value=False,
525+
),
521526
):
522527
yield
523528

tests/streamlit/streamlit_test_class.py

Lines changed: 20 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
from pathlib import Path
1+
from re import match
22
from typing import List
33
from unittest import mock
4-
from unittest.mock import MagicMock
54

6-
from snowflake.core.stage import StageResource
5+
from tests.conftest import MockCursor
76

87
STREAMLIT_NAME = "test_streamlit"
98

@@ -26,16 +25,17 @@ def setup_method(self):
2625

2726
self.mock_execute = mock.patch(EXECUTE_QUERY).start()
2827

29-
mock_stage_resource = StageResource(
30-
name="stage_resource_mock", collection=MagicMock()
31-
)
3228
self.mock_create_stage = mock.patch(
33-
"snowflake.cli._plugins.streamlit.streamlit_entity.StreamlitEntity._create_stage_if_not_exists",
34-
return_value=mock_stage_resource,
29+
"snowflake.cli._plugins.stage.manager.StageManager.create",
30+
).start()
31+
32+
self.mock_list_files = mock.patch(
33+
"snowflake.cli._plugins.stage.manager.StageManager.list_files",
34+
return_value=MockCursor.from_input([], []),
3535
).start()
3636

3737
self.mock_put = mock.patch(
38-
"snowflake.core.stage._stage.StageResource.put"
38+
"snowflake.cli._plugins.stage.manager.StageManager.put"
3939
).start()
4040

4141
self.mock_get_account = mock.patch(
@@ -61,19 +61,14 @@ def _assert_that_exactly_those_files_were_put_to_stage(
6161
put_files: List[str],
6262
streamlit_name: str = "test_streamlit",
6363
):
64-
assert self.mock_put.call_count == len(put_files) # type: ignore
65-
66-
for file in put_files:
67-
if isinstance(file, dict):
68-
local = Path(file["local"])
69-
stage = f"/{streamlit_name}{file['stage'] if file['stage'] else ''}"
70-
else:
71-
local = Path(file)
72-
stage = f"/{streamlit_name}/{str(Path(file).parent) if Path(file).parent != Path('.') else ''}"
73-
74-
self.mock_put.assert_any_call( # type: ignore
75-
local_file_name=local,
76-
stage_location=stage,
77-
overwrite=True,
78-
auto_compress=False,
79-
)
64+
# assert self.mock_put.call_count == len(put_files) # type: ignore
65+
66+
re_local_path = f".*/{streamlit_name}/(?P<filename>.*)"
67+
uploaded_files = set()
68+
for call in self.mock_put.call_args_list:
69+
if path := call.kwargs.get("local_path"):
70+
matched_path = match(re_local_path, path.as_posix())
71+
if matched_path:
72+
uploaded_files.add(matched_path.group("filename"))
73+
74+
assert set(put_files) == uploaded_files, uploaded_files

0 commit comments

Comments
 (0)