cloud-files 4.24.2__tar.gz → 4.26.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {cloud-files-4.24.2 → cloud-files-4.26.0}/ChangeLog +11 -0
- {cloud-files-4.24.2 → cloud-files-4.26.0}/PKG-INFO +1 -1
- {cloud-files-4.24.2 → cloud-files-4.26.0}/cloud_files.egg-info/PKG-INFO +1 -1
- cloud-files-4.26.0/cloud_files.egg-info/pbr.json +1 -0
- {cloud-files-4.24.2 → cloud-files-4.26.0}/cloudfiles/interfaces.py +53 -0
- {cloud-files-4.24.2 → cloud-files-4.26.0}/cloudfiles/paths.py +18 -6
- {cloud-files-4.24.2 → cloud-files-4.26.0}/setup.py +3 -0
- cloud-files-4.24.2/cloud_files.egg-info/pbr.json +0 -1
- {cloud-files-4.24.2 → cloud-files-4.26.0}/.github/workflows/test-suite.yml +0 -0
- {cloud-files-4.24.2 → cloud-files-4.26.0}/AUTHORS +0 -0
- {cloud-files-4.24.2 → cloud-files-4.26.0}/LICENSE +0 -0
- {cloud-files-4.24.2 → cloud-files-4.26.0}/MANIFEST.in +0 -0
- {cloud-files-4.24.2 → cloud-files-4.26.0}/README.md +0 -0
- {cloud-files-4.24.2 → cloud-files-4.26.0}/automated_test.py +0 -0
- {cloud-files-4.24.2 → cloud-files-4.26.0}/cloud_files.egg-info/SOURCES.txt +0 -0
- {cloud-files-4.24.2 → cloud-files-4.26.0}/cloud_files.egg-info/dependency_links.txt +0 -0
- {cloud-files-4.24.2 → cloud-files-4.26.0}/cloud_files.egg-info/entry_points.txt +0 -0
- {cloud-files-4.24.2 → cloud-files-4.26.0}/cloud_files.egg-info/not-zip-safe +0 -0
- {cloud-files-4.24.2 → cloud-files-4.26.0}/cloud_files.egg-info/requires.txt +0 -0
- {cloud-files-4.24.2 → cloud-files-4.26.0}/cloud_files.egg-info/top_level.txt +0 -0
- {cloud-files-4.24.2 → cloud-files-4.26.0}/cloudfiles/__init__.py +0 -0
- {cloud-files-4.24.2 → cloud-files-4.26.0}/cloudfiles/cloudfiles.py +0 -0
- {cloud-files-4.24.2 → cloud-files-4.26.0}/cloudfiles/compression.py +0 -0
- {cloud-files-4.24.2 → cloud-files-4.26.0}/cloudfiles/connectionpools.py +0 -0
- {cloud-files-4.24.2 → cloud-files-4.26.0}/cloudfiles/exceptions.py +0 -0
- {cloud-files-4.24.2 → cloud-files-4.26.0}/cloudfiles/gcs.py +0 -0
- {cloud-files-4.24.2 → cloud-files-4.26.0}/cloudfiles/lib.py +0 -0
- {cloud-files-4.24.2 → cloud-files-4.26.0}/cloudfiles/resumable_tools.py +0 -0
- {cloud-files-4.24.2 → cloud-files-4.26.0}/cloudfiles/scheduler.py +0 -0
- {cloud-files-4.24.2 → cloud-files-4.26.0}/cloudfiles/secrets.py +0 -0
- {cloud-files-4.24.2 → cloud-files-4.26.0}/cloudfiles/threaded_queue.py +0 -0
- {cloud-files-4.24.2 → cloud-files-4.26.0}/cloudfiles/typing.py +0 -0
- {cloud-files-4.24.2 → cloud-files-4.26.0}/cloudfiles_cli/LICENSE +0 -0
- {cloud-files-4.24.2 → cloud-files-4.26.0}/cloudfiles_cli/__init__.py +0 -0
- {cloud-files-4.24.2 → cloud-files-4.26.0}/cloudfiles_cli/cloudfiles_cli.py +0 -0
- {cloud-files-4.24.2 → cloud-files-4.26.0}/requirements.txt +0 -0
- {cloud-files-4.24.2 → cloud-files-4.26.0}/setup.cfg +0 -0
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
CHANGES
|
|
2
2
|
=======
|
|
3
3
|
|
|
4
|
+
4.26.0
|
|
5
|
+
------
|
|
6
|
+
|
|
7
|
+
* feat: make it possible to normalize e.g. zarr2://./helloworld
|
|
8
|
+
* feat: add all current neuroglancer formats to parsing list
|
|
9
|
+
|
|
10
|
+
4.25.0
|
|
11
|
+
------
|
|
12
|
+
|
|
13
|
+
* feat: list for apache servers (#104)
|
|
14
|
+
|
|
4
15
|
4.24.2
|
|
5
16
|
------
|
|
6
17
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"git_version": "3ae7c76", "is_release": true}
|
|
@@ -714,6 +714,8 @@ class GoogleCloudStorageInterface(StorageInterface):
|
|
|
714
714
|
pool.release_connection(self._bucket)
|
|
715
715
|
|
|
716
716
|
class HttpInterface(StorageInterface):
|
|
717
|
+
adaptor = requests.adapters.HTTPAdapter()
|
|
718
|
+
|
|
717
719
|
def __init__(self, path, secrets=None, request_payer=None, **kwargs):
|
|
718
720
|
super(StorageInterface, self).__init__()
|
|
719
721
|
self._path = path
|
|
@@ -724,6 +726,8 @@ class HttpInterface(StorageInterface):
|
|
|
724
726
|
secrets = http_credentials()
|
|
725
727
|
|
|
726
728
|
self.session = requests.Session()
|
|
729
|
+
self.session.mount('http://', self.adaptor)
|
|
730
|
+
self.session.mount('https://', self.adaptor)
|
|
727
731
|
if secrets and 'user' in secrets and 'password' in secrets:
|
|
728
732
|
self.session.auth = (secrets['user'], secrets['password'])
|
|
729
733
|
|
|
@@ -822,9 +826,58 @@ class HttpInterface(StorageInterface):
|
|
|
822
826
|
if token is None:
|
|
823
827
|
break
|
|
824
828
|
|
|
829
|
+
def _list_files_apache(self, prefix, flat):
|
|
830
|
+
import lxml.html
|
|
831
|
+
|
|
832
|
+
baseurl = posixpath.join(self._path.host, self._path.path)
|
|
833
|
+
|
|
834
|
+
directories = ['']
|
|
835
|
+
|
|
836
|
+
while directories:
|
|
837
|
+
directory = directories.pop()
|
|
838
|
+
url = posixpath.join(baseurl, directory)
|
|
839
|
+
|
|
840
|
+
resp = requests.get(url)
|
|
841
|
+
resp.raise_for_status()
|
|
842
|
+
|
|
843
|
+
if 'text/html' not in resp.headers["Content-Type"]:
|
|
844
|
+
raise ValueError("Unable to parse non-HTML output from Apache servers.")
|
|
845
|
+
|
|
846
|
+
entities = lxml.html.document_fromstring(resp.content)
|
|
847
|
+
resp.close()
|
|
848
|
+
|
|
849
|
+
h1 = entities.xpath("body/h1")[0].text_content()
|
|
850
|
+
if "Index of" not in h1:
|
|
851
|
+
raise ValueError("Unable to parse non-index page.")
|
|
852
|
+
|
|
853
|
+
for li in entities.xpath("body/ul/li"):
|
|
854
|
+
txt = li.text_content().strip()
|
|
855
|
+
if txt == "Parent Directory":
|
|
856
|
+
continue
|
|
857
|
+
|
|
858
|
+
txt = posixpath.join(directory, txt)
|
|
859
|
+
if prefix and not txt.startswith(prefix):
|
|
860
|
+
continue
|
|
861
|
+
|
|
862
|
+
if txt[-1] == '/':
|
|
863
|
+
directories.append(txt)
|
|
864
|
+
continue
|
|
865
|
+
|
|
866
|
+
yield txt
|
|
867
|
+
|
|
868
|
+
if flat:
|
|
869
|
+
break
|
|
870
|
+
|
|
825
871
|
def list_files(self, prefix, flat=False):
|
|
826
872
|
if self._path.host == "https://storage.googleapis.com":
|
|
827
873
|
yield from self._list_files_google(prefix, flat)
|
|
874
|
+
|
|
875
|
+
url = posixpath.join(self._path.host, self._path.path, prefix)
|
|
876
|
+
resp = requests.head(url)
|
|
877
|
+
|
|
878
|
+
server = resp.headers.get("Server", "").lower()
|
|
879
|
+
if 'apache' in server:
|
|
880
|
+
yield from self._list_files_apache(prefix, flat)
|
|
828
881
|
else:
|
|
829
882
|
raise NotImplementedError()
|
|
830
883
|
|
|
@@ -29,7 +29,12 @@ BASE_ALLOWED_PROTOCOLS = [
|
|
|
29
29
|
'http', 'https', 'mem'
|
|
30
30
|
]
|
|
31
31
|
ALLOWED_PROTOCOLS = list(BASE_ALLOWED_PROTOCOLS)
|
|
32
|
-
ALLOWED_FORMATS = [
|
|
32
|
+
ALLOWED_FORMATS = [
|
|
33
|
+
'graphene', 'precomputed', 'boss',
|
|
34
|
+
'n5', 'zarr', 'zarr2', 'zarr3',
|
|
35
|
+
'brainmaps', 'deepzoom', 'nggraph',
|
|
36
|
+
'render', 'vtk', 'nifti', 'dvid',
|
|
37
|
+
]
|
|
33
38
|
|
|
34
39
|
def update_aliases_from_file():
|
|
35
40
|
global ALIASES_FROM_FILE
|
|
@@ -147,11 +152,16 @@ for alias, host in OFFICIAL_ALIASES.items():
|
|
|
147
152
|
## Other Path Library Functions
|
|
148
153
|
|
|
149
154
|
def normalize(path):
|
|
150
|
-
proto =
|
|
155
|
+
fmt, proto, endpoint, cloudpath, alias = extract_format_protocol(
|
|
156
|
+
path, allow_defaults=False
|
|
157
|
+
)
|
|
158
|
+
|
|
151
159
|
if proto is None:
|
|
152
160
|
proto = "file"
|
|
153
|
-
|
|
154
|
-
|
|
161
|
+
cloudpath = toabs(cloudpath)
|
|
162
|
+
fmt = f"{fmt}://" if fmt else ""
|
|
163
|
+
path = f"{fmt}{proto}://{cloudpath}"
|
|
164
|
+
|
|
155
165
|
return path
|
|
156
166
|
|
|
157
167
|
def dirname(path):
|
|
@@ -264,7 +274,7 @@ def pop_protocol(cloudpath):
|
|
|
264
274
|
|
|
265
275
|
return (protocol, cloudpath)
|
|
266
276
|
|
|
267
|
-
def extract_format_protocol(cloudpath:str) -> tuple:
|
|
277
|
+
def extract_format_protocol(cloudpath:str, allow_defaults=True) -> tuple:
|
|
268
278
|
error = UnsupportedProtocolError(cloudpath_error(cloudpath))
|
|
269
279
|
|
|
270
280
|
alias, cloudpath = resolve_alias(cloudpath)
|
|
@@ -276,7 +286,9 @@ def extract_format_protocol(cloudpath:str) -> tuple:
|
|
|
276
286
|
groups = m.groups()
|
|
277
287
|
cloudpath = re.sub(CLOUDPATH_REGEXP, '', cloudpath, count=1)
|
|
278
288
|
|
|
279
|
-
fmt = m.group('fmt')
|
|
289
|
+
fmt = m.group('fmt')
|
|
290
|
+
if not fmt and allow_defaults:
|
|
291
|
+
fmt = 'precomputed'
|
|
280
292
|
proto = m.group('proto')
|
|
281
293
|
endpoint = None
|
|
282
294
|
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"git_version": "84826ee", "is_release": true}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|