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

Append to file when opened with mode a #38

Merged
merged 2 commits into from
Nov 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 20 additions & 4 deletions tests/test_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,19 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from v3iofs import V3ioFile, V3ioFS
from v3iofs import V3ioFS


def test_fetch_range(fs: V3ioFS, tmp_obj):
v3f = V3ioFile(fs, tmp_obj.path)
v3f = fs.open(tmp_obj.path)
start, end = 3, len(tmp_obj.data) - 3
data = v3f._fetch_range(start, end)
expected = tmp_obj.data[start:end]
assert expected == data, "bad data"


def test_upload_chunk(fs: V3ioFS, tmp_obj):
v3f = V3ioFile(fs, tmp_obj.path, "ab")
v3f = fs.open(tmp_obj.path, "ab")
chunk = b"::chunk of data"
v3f.buffer.write(chunk)
v3f._upload_chunk()
Expand All @@ -37,10 +37,26 @@ def test_upload_chunk(fs: V3ioFS, tmp_obj):
assert expected == data, "bad data"


def test_write_truncate_and_append(fs: V3ioFS, tmp_obj):
with fs.open(tmp_obj.path, "wb") as v3f:
v3f.write(b"123")

with fs.open(tmp_obj.path, "rb") as fp:
data = fp.read()
assert data == b"123"

with fs.open(tmp_obj.path, "ab") as v3f:
v3f.write(b"456")

with fs.open(tmp_obj.path, "rb") as fp:
data = fp.read()
assert data == b"123456"


def test_initiate_upload(fs: V3ioFS, tmp_obj):
fs.touch(tmp_obj.path)
assert fs.exists(tmp_obj.path)
v3f = V3ioFile(fs, tmp_obj.path, "wb")
v3f = fs.open(tmp_obj.path, "wb")
v3f._initiate_upload()
assert not fs.exists(tmp_obj.path)
# should not fail even if the file does not exist
Expand Down
3 changes: 2 additions & 1 deletion v3iofs/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,5 @@ def _upload_chunk(self, final=False):

def _initiate_upload(self):
"""Create remote file/upload"""
self.fs.rm_file(self.path)
if "a" not in self.mode:
self.fs.rm_file(self.path)
18 changes: 15 additions & 3 deletions v3iofs/fs.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,16 +96,20 @@ class V3ioFS(AbstractFileSystem):
cache_capacity: int | str | None
limits the size of the cache. If cache_validity_seconds is not set, this parameter has no effect.
Default is 128.
debug: bool
Turn on transport debug logs. Default is False.
**kw:
Passed to fsspec.AbstractFileSystem
"""

protocol = "v3io"

def __init__(self, v3io_api=None, v3io_access_key=None, cache_validity_seconds=None, cache_capacity=None, **kw):
def __init__(
self, v3io_api=None, v3io_access_key=None, cache_validity_seconds=None, cache_capacity=None, debug=False, **kw
):
# TODO: Support storage options for creds (in kw)
super().__init__(**kw)
self._client = _new_client(v3io_api, v3io_access_key)
self._client = _new_client(v3io_api, v3io_access_key, debug)
self._cache = None
if cache_validity_seconds is None:
cache_validity_seconds = 2
Expand Down Expand Up @@ -338,6 +342,8 @@ def _open(
cache_options=None,
**kw,
):
if mode != "rb":
self._cache.delete_if_exists(path)
return V3ioFile(
fs=self,
path=path,
Expand Down Expand Up @@ -450,11 +456,17 @@ def _has_data(resp):
return hasattr(out, "common_prefixes") or hasattr(out, "contents")


def _new_client(v3io_api=None, v3io_access_key=None) -> Client:
def _new_client(v3io_api=None, v3io_access_key=None, debug=False) -> Client:
v3io_api = v3io_api or environ.get("V3IO_API")
v3io_access_key = v3io_access_key or environ.get("V3IO_ACCESS_KEY")

client_kwargs = {}
if debug:
client_kwargs["logger_verbosity"] = "DEBUG"
client_kwargs["transport_verbosity"] = "DEBUG"

return Client(
endpoint=v3io_api,
access_key=v3io_access_key,
**client_kwargs,
)