Skip to content

Commit 88c85ec

Browse files
authored
[SNOW-2138082]: Add relative path support for SnowflakeFile (#3571)
1 parent 1d66c2d commit 88c85ec

File tree

2 files changed

+42
-14
lines changed

2 files changed

+42
-14
lines changed

src/snowflake/snowpark/files.py

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
SEEK_CUR,
1818
)
1919
from snowflake.snowpark._internal.utils import (
20-
RELATIVE_PATH_PREFIX,
2120
SNOWFLAKE_PATH_PREFIXES,
2221
)
2322
from typing import Sequence
@@ -82,6 +81,7 @@ class SnowflakeFile(RawIOBase):
8281
We provide a local implementation of SnowflakeFile to aid in local testing.
8382
This currently supports using read APIs on relative paths, mocked stages
8483
(sessions in local testing mode that aren't connected to a real stage), and Snowflake stages.
84+
Scoped and Stage URLs (https://) are not yet supported.
8585
8686
Note:
8787
1. All of the implementation in this file is for local testing purposes.
@@ -119,25 +119,17 @@ def __init__(
119119
# Attributes required for local testing functionality
120120
_DEFAULT_READ_BUFFER_SIZE = 32 * 1024
121121
self._pos = 0
122-
self._is_local_file = (
123-
True
124-
if self._file_location.startswith((RELATIVE_PATH_PREFIX, "C:"))
125-
else False
126-
)
122+
if self._file_location.startswith("https://"):
123+
raise ValueError("Scoped and Stage URLs are not yet supported.")
124+
127125
self._is_stage_file = (
128126
True
129127
if self._file_location.startswith(tuple(SNOWFLAKE_PATH_PREFIXES))
130128
else False
131129
)
132-
133-
# Validate the file location
134-
if not self._is_local_file and not self._is_stage_file:
135-
raise ValueError(
136-
f"Invalid file location '{self._file_location}'. "
137-
"File location must be a local file path or a stage file URL."
138-
)
139-
130+
self._is_local_file = not self._is_stage_file
140131
self._file_size = 0
132+
141133
if self._is_local_file and mode in _READ_MODES:
142134
# Buffered Reader used to support BufferedIOBase methods such as read1 and readinto1
143135
encoding = "utf-8" if mode == "r" else None

tests/unit/test_files.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,42 @@ def sf_open(file_location: str) -> None:
352352
sf_open(temp_file)
353353

354354

355+
@pytest.mark.parametrize(
356+
["read_mode", "write_mode", "use_tmp_path"],
357+
[("r", "w", True), ("r", "w", False), ("rb", "wb", True), ("rb", "wb", False)],
358+
)
359+
def test_read_relative_path_snowflakefile(
360+
read_mode, write_mode, use_tmp_path, tmp_path
361+
):
362+
if use_tmp_path:
363+
test_msg, temp_file = Utils.write_test_msg(write_mode, tmp_path)
364+
else:
365+
# Write to a temp file in the current directory
366+
test_msg, temp_file = Utils.write_test_msg(write_mode, "")
367+
temp_file = os.path.relpath(temp_file)
368+
369+
def read_file(file_location: str, mode: str) -> Union[str, bytes]:
370+
with SnowflakeFile.open(file_location, mode) as f:
371+
return f.read()
372+
373+
assert read_file(temp_file, read_mode) == test_msg
374+
if not use_tmp_path:
375+
os.remove(temp_file)
376+
377+
378+
def test_read_scoped_url_snowflakefile():
379+
scoped_url = "https://example.com/path/to/file.txt"
380+
381+
def read_file(file_location: str, mode: str) -> Union[str, bytes]:
382+
with SnowflakeFile.open(file_location, mode) as f:
383+
return f.read()
384+
385+
with pytest.raises(
386+
ValueError, match="Scoped and Stage URLs are not yet supported."
387+
):
388+
read_file(scoped_url, "r")
389+
390+
355391
@pytest.mark.parametrize(
356392
_STANDARD_ARGS,
357393
_STANDARD_ARGVALUES,

0 commit comments

Comments
 (0)