Skip to content
This repository has been archived by the owner on Nov 7, 2024. It is now read-only.

Commit

Permalink
Make the transform less useful by requiring the caller to do more work.
Browse files Browse the repository at this point in the history
  • Loading branch information
manthey committed Nov 15, 2018
1 parent 0f416e4 commit 789b972
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 65 deletions.
70 changes: 18 additions & 52 deletions girder_worker_utils/tests/contrib/girder_io_test.py
Original file line number Diff line number Diff line change
@@ -1,56 +1,11 @@
import os
import sys
import types

import girder_client
import mock
import os
import pytest

from girder_worker_utils.transforms.contrib import girder_io


@pytest.fixture
def mock_file_model():
girder = types.ModuleType('girder')
girder.models = types.ModuleType('models')
girder.models.file = types.ModuleType('file')
sys.modules['girder'] = girder
sys.modules['girder.models'] = girder.models
sys.modules['girder.models.file'] = girder.models.file
girder.exceptions = types.ModuleType('exceptions')
sys.modules['girder.exceptions'] = girder.exceptions

def fileObject():
pass

girder.models.file.File = lambda: fileObject
return girder.models.file.File()


@pytest.fixture
def mock_file_load(mock_file_model):
from girder.models.file import File

def load(*args, **kwargs):
return {'name': 'the_name'}

File().load = load
return File()


@pytest.fixture
def mock_file_getLocalFilePath(mock_file_model):
import girder.exceptions
from girder.models.file import File

girder.exceptions.FilePathException = Exception

def getLocalFilePath(*args, **kwargs):
return os.path.realpath(__file__)

File().getLocalFilePath = getLocalFilePath


@pytest.fixture
def mock_gc():
return mock.MagicMock(spec=girder_client.GirderClient)
Expand All @@ -62,9 +17,9 @@ def mock_rmtree():
yield rmtree


def test_GirderFileIdAllowDirect_without_env(
mock_gc, mock_rmtree, mock_file_load, mock_file_getLocalFilePath):
t = girder_io.GirderFileIdAllowDirect(_id='the_id', gc=mock_gc)
def test_GirderFileIdAllowDirect_without_env(mock_gc, mock_rmtree):
local_path = os.path.abspath(__file__)
t = girder_io.GirderFileIdAllowDirect('the_id', 'the_name', local_path, gc=mock_gc)
t.transform()
mock_gc.downloadFile.assert_called_once()
assert 'the_id' in mock_gc.downloadFile.call_args[0]
Expand All @@ -74,10 +29,21 @@ def test_GirderFileIdAllowDirect_without_env(


@mock.patch.dict(os.environ, {'GW_DIRECT_PATHS': 'true'})
def test_GirderFileIdAllowDirect_with_env(
mock_gc, mock_rmtree, mock_file_load, mock_file_getLocalFilePath):
t = girder_io.GirderFileIdAllowDirect(_id='the_id', gc=mock_gc)
def test_GirderFileIdAllowDirect_with_env(mock_gc, mock_rmtree):
local_path = os.path.abspath(__file__)
t = girder_io.GirderFileIdAllowDirect('the_id', 'the_name', local_path, gc=mock_gc)
t.transform()
mock_gc.downloadFile.assert_not_called()
t.cleanup()
mock_rmtree.assert_not_called()


@mock.patch.dict(os.environ, {'GW_DIRECT_PATHS': 'true'})
def test_GirderFileIdAllowDirect_with_env_and_unreachable_file(mock_gc, mock_rmtree):
t = girder_io.GirderFileIdAllowDirect('the_id', 'the_name', 'the_path', gc=mock_gc)
t.transform()
mock_gc.downloadFile.assert_called_once()
assert 'the_id' in mock_gc.downloadFile.call_args[0]
mock_rmtree.assert_not_called()
t.cleanup()
mock_rmtree.assert_called_once()
34 changes: 21 additions & 13 deletions girder_worker_utils/transforms/contrib/girder_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,29 +9,37 @@ class GirderFileIdAllowDirect(GirderClientTransform):
"""
This transform either uses direct path to access a file, if possible and
allowed, or downloads a Girder File to the local machine and passes its
local path into the function.
local path into the function. The direct path is only used if the
GW_DIRECT_PATHS environment variable is set.
WARNING: if a direct path is used, the task MUST NOT modify the file. It
is the resposibility of the user of this transform to ensure tasks treat
files as read-only.
To use this transform from Girder, it should be called via something like:
```
try:
local_path = File().getLocalFilePath(file)
except FilePathException:
local_path = None
input_path = GirderFileIdAllowDirect(
str(file['_id']), file['name'], local_path)
```
:param _id: The ID of the file to download.
:type _id: str
:param name: The name of the file. If the file must be downloaded, the
extension is preserved.
:type name: str
:param local_path: If specified and the path exists and is reachable by
after the transform, the file is accessed directly.
:type local_path: str
"""
def __init__(self, _id, **kwargs):
def __init__(self, _id, name='', local_path=None, **kwargs):
super(GirderFileIdAllowDirect, self).__init__(**kwargs)
from girder.models.file import File
from girder.exceptions import FilePathException
self.file_id = _id
file = File().load(self.file_id, force=True)
# Store the original file name so that, if downloading the file, the
# extension can be preserved.
self.file_name = file['name']
try:
# Add a local file path if direct paths are allowed
self.local_file_path = File().getLocalFilePath(file)
except FilePathException:
self.local_file_path = None
self.file_name = name
self.local_file_path = local_path

def _repr_model_(self):
if self.local_file_path:
Expand Down

0 comments on commit 789b972

Please sign in to comment.