diff --git a/README.rst b/README.rst index 8ccb7b1..22e6aa5 100644 --- a/README.rst +++ b/README.rst @@ -8,6 +8,15 @@ As a PyFilesystem concrete class, `S3FS `__ allows you to work with S3 in the same way as any other supported filesystem. +Installing +---------- + +You can install S3FS from pip as follows: + +:: + + pip install fs-s3fs + Opening a S3FS -------------- @@ -15,7 +24,7 @@ Open an S3FS by explicitly using the constructor: .. code:: python - from s3_s3fs import s3FS + from s3_s3fs import S3FS s3fs = S3FS('mybucket') Or with a FS URL: diff --git a/fs_s3fs/_s3fs.py b/fs_s3fs/_s3fs.py index e231154..f2808f2 100644 --- a/fs_s3fs/_s3fs.py +++ b/fs_s3fs/_s3fs.py @@ -24,6 +24,7 @@ from fs.info import Info from fs import errors from fs.mode import Mode +from fs.subfs import SubFS from fs.path import basename, dirname, forcedir, join, normpath, relpath from fs.time import datetime_to_epoch @@ -336,8 +337,6 @@ def _get_object(self, path, key): ) obj.load() return obj - except Exception: - raise else: return obj @@ -410,6 +409,13 @@ def _info_from_object(self, obj, namespaces): } return info + def isdir(self, path): + _path = self.validatepath(path) + try: + return self._getinfo(_path).is_dir + except errors.ResourceNotFound: + return False + def getinfo(self, path, namespaces=None): self.check() namespaces = namespaces or () @@ -420,7 +426,11 @@ def getinfo(self, path, namespaces=None): dir_path = dirname(_path) if dir_path != '/': _dir_key = self._path_to_dir_key(dir_path) - self._get_object(dir_path, _dir_key) + with s3errors(path): + obj = self.s3.Object( + self._bucket_name, _dir_key + ) + obj.load() except errors.ResourceNotFound: raise errors.ResourceNotFound(path) @@ -441,6 +451,28 @@ def getinfo(self, path, namespaces=None): info = self._info_from_object(obj, namespaces) return Info(info) + def _getinfo(self, path, namespaces=None): + """Gets info without checking for parent dir.""" + namespaces = namespaces or () + _path = self.validatepath(path) + _key = self._path_to_key(_path) + if _path == '/': + return Info({ + "basic": + { + "name": "", + "is_dir": True + }, + "details": + { + "type": int(ResourceType.directory) + } + }) + + obj = self._get_object(path, _key) + info = self._info_from_object(obj, namespaces) + return Info(info) + def listdir(self, path): _path = self.validatepath(path) _s3_key = self._path_to_dir_key(_path) @@ -481,7 +513,7 @@ def makedir(self, path, permissions=None, recreate=False): raise errors.ResourceNotFound(path) try: - self.getinfo(path) + self._getinfo(path) except errors.ResourceNotFound: pass else: @@ -491,7 +523,7 @@ def makedir(self, path, permissions=None, recreate=False): raise errors.DirectoryExists(path) with s3errors(path): self.s3.Object(self._bucket_name, _key).put() - return self.opendir(path) + return SubFS(self, path) def openbin(self, path, mode="r", buffering=-1, **options): _mode = Mode(mode) @@ -514,7 +546,15 @@ def on_close_create(s3file): s3file.raw.close() try: - info = self.getinfo(path) + dir_path = dirname(_path) + if dir_path != '/': + _dir_key = self._path_to_dir_key(dir_path) + self._get_object(dir_path, _dir_key) + except errors.ResourceNotFound: + raise errors.ResourceNotFound(path) + + try: + info = self._getinfo(path) except errors.ResourceNotFound: pass else: @@ -709,7 +749,7 @@ def setbytes(self, path, contents): if not self.isdir(dirname(path)): raise errors.ResourceNotFound(path) try: - info = self.getinfo(path) + info = self._getinfo(path) if info.is_dir: raise errors.FileExpected(path) except errors.ResourceNotFound: @@ -729,7 +769,7 @@ def setbinfile(self, path, file): if not self.isdir(dirname(path)): raise errors.ResourceNotFound(path) try: - info = self.getinfo(path) + info = self._getinfo(path) if info.is_dir: raise errors.FileExpected(path) except errors.ResourceNotFound: diff --git a/fs_s3fs/_version.py b/fs_s3fs/_version.py index 0a8da88..f1380ee 100644 --- a/fs_s3fs/_version.py +++ b/fs_s3fs/_version.py @@ -1 +1 @@ -__version__ = "0.1.6" +__version__ = "0.1.7"