Skip to content
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
22 changes: 16 additions & 6 deletions sqlalchemy_file/storage.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import contextlib
import warnings
from typing import Any, ClassVar, Dict, Iterator, Optional
from typing import Any, ClassVar, Dict, Iterator, Optional, Tuple

from libcloud.storage.base import Container
from libcloud.storage.types import ObjectDoesNotExistError
Expand Down Expand Up @@ -122,10 +122,11 @@ def save_file(

@classmethod
def get_file(cls, path: str) -> StoredFile:
"""Retrieve the file with `provided` path,
path is expected to be `storage_name/file_id`.
"""Retrieve the file with `provided` path.

The path is expected to be `storage_name/file_id`.
"""
upload_storage, file_id = path.split("/")
upload_storage, file_id = cls._get_storage_and_file_id(path)
return StoredFile(StorageManager.get(upload_storage).get_object(file_id))

@classmethod
Expand All @@ -134,7 +135,7 @@ def delete_file(cls, path: str) -> bool:

The path is expected to be `storage_name/file_id`.
"""
upload_storage, file_id = path.split("/")
upload_storage, file_id = cls._get_storage_and_file_id(path)
obj = StorageManager.get(upload_storage).get_object(file_id)
if obj.driver.name == LOCAL_STORAGE_DRIVER_NAME:
"""Try deleting associated metadata file"""
Expand All @@ -145,6 +146,15 @@ def delete_file(cls, path: str) -> bool:

@classmethod
def _clear(cls) -> None:
"""This is only for testing pourposes, resets the StorageManager."""
"""This is only for testing purposes, resets the StorageManager."""
cls._default_storage_name = None
cls._storages = {}

@classmethod
def _get_storage_and_file_id(cls, path: str) -> Tuple[str, str]:
"""Extract the storage name and file_id from the path.

The path is expected to be `storage_name/file_id`.
"""
path_parts = path.split("/")
return "/".join(path_parts[:-1]), path_parts[-1]
19 changes: 19 additions & 0 deletions tests/test_storage_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,16 @@ class TestStorageManager:
def setup_method(self, method) -> None:
StorageManager._clear()

def test_get_storage_and_file_id(self) -> None:
assert StorageManager._get_storage_and_file_id("storage/file") == (
"storage",
"file",
)
assert StorageManager._get_storage_and_file_id("storage/folder/file") == (
"storage/folder",
"file",
)

def test_first_configured_is_default(self) -> None:
StorageManager.add_storage("first", get_dummy_container("first"))
StorageManager.add_storage("second", get_dummy_container("second"))
Expand All @@ -19,6 +29,15 @@ def test_changing_default_storage_works(self) -> None:
StorageManager.set_default("second")
assert StorageManager.get_default() == "second"

def test_complex_storage_name(self) -> None:
StorageManager.add_storage(
"storage/folder", get_dummy_container("storage/folder")
)
StorageManager.add_storage(
"storage/folder/subfolder", get_dummy_container("storage/folder/subfolder")
)
assert StorageManager.get_default() == "storage/folder"

def test_no_storage_is_detected(self) -> None:
with pytest.raises(RuntimeError):
StorageManager.get_default()
Expand Down