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.
Files changed (37) hide show
  1. {cloud-files-4.24.2 → cloud-files-4.26.0}/ChangeLog +11 -0
  2. {cloud-files-4.24.2 → cloud-files-4.26.0}/PKG-INFO +1 -1
  3. {cloud-files-4.24.2 → cloud-files-4.26.0}/cloud_files.egg-info/PKG-INFO +1 -1
  4. cloud-files-4.26.0/cloud_files.egg-info/pbr.json +1 -0
  5. {cloud-files-4.24.2 → cloud-files-4.26.0}/cloudfiles/interfaces.py +53 -0
  6. {cloud-files-4.24.2 → cloud-files-4.26.0}/cloudfiles/paths.py +18 -6
  7. {cloud-files-4.24.2 → cloud-files-4.26.0}/setup.py +3 -0
  8. cloud-files-4.24.2/cloud_files.egg-info/pbr.json +0 -1
  9. {cloud-files-4.24.2 → cloud-files-4.26.0}/.github/workflows/test-suite.yml +0 -0
  10. {cloud-files-4.24.2 → cloud-files-4.26.0}/AUTHORS +0 -0
  11. {cloud-files-4.24.2 → cloud-files-4.26.0}/LICENSE +0 -0
  12. {cloud-files-4.24.2 → cloud-files-4.26.0}/MANIFEST.in +0 -0
  13. {cloud-files-4.24.2 → cloud-files-4.26.0}/README.md +0 -0
  14. {cloud-files-4.24.2 → cloud-files-4.26.0}/automated_test.py +0 -0
  15. {cloud-files-4.24.2 → cloud-files-4.26.0}/cloud_files.egg-info/SOURCES.txt +0 -0
  16. {cloud-files-4.24.2 → cloud-files-4.26.0}/cloud_files.egg-info/dependency_links.txt +0 -0
  17. {cloud-files-4.24.2 → cloud-files-4.26.0}/cloud_files.egg-info/entry_points.txt +0 -0
  18. {cloud-files-4.24.2 → cloud-files-4.26.0}/cloud_files.egg-info/not-zip-safe +0 -0
  19. {cloud-files-4.24.2 → cloud-files-4.26.0}/cloud_files.egg-info/requires.txt +0 -0
  20. {cloud-files-4.24.2 → cloud-files-4.26.0}/cloud_files.egg-info/top_level.txt +0 -0
  21. {cloud-files-4.24.2 → cloud-files-4.26.0}/cloudfiles/__init__.py +0 -0
  22. {cloud-files-4.24.2 → cloud-files-4.26.0}/cloudfiles/cloudfiles.py +0 -0
  23. {cloud-files-4.24.2 → cloud-files-4.26.0}/cloudfiles/compression.py +0 -0
  24. {cloud-files-4.24.2 → cloud-files-4.26.0}/cloudfiles/connectionpools.py +0 -0
  25. {cloud-files-4.24.2 → cloud-files-4.26.0}/cloudfiles/exceptions.py +0 -0
  26. {cloud-files-4.24.2 → cloud-files-4.26.0}/cloudfiles/gcs.py +0 -0
  27. {cloud-files-4.24.2 → cloud-files-4.26.0}/cloudfiles/lib.py +0 -0
  28. {cloud-files-4.24.2 → cloud-files-4.26.0}/cloudfiles/resumable_tools.py +0 -0
  29. {cloud-files-4.24.2 → cloud-files-4.26.0}/cloudfiles/scheduler.py +0 -0
  30. {cloud-files-4.24.2 → cloud-files-4.26.0}/cloudfiles/secrets.py +0 -0
  31. {cloud-files-4.24.2 → cloud-files-4.26.0}/cloudfiles/threaded_queue.py +0 -0
  32. {cloud-files-4.24.2 → cloud-files-4.26.0}/cloudfiles/typing.py +0 -0
  33. {cloud-files-4.24.2 → cloud-files-4.26.0}/cloudfiles_cli/LICENSE +0 -0
  34. {cloud-files-4.24.2 → cloud-files-4.26.0}/cloudfiles_cli/__init__.py +0 -0
  35. {cloud-files-4.24.2 → cloud-files-4.26.0}/cloudfiles_cli/cloudfiles_cli.py +0 -0
  36. {cloud-files-4.24.2 → cloud-files-4.26.0}/requirements.txt +0 -0
  37. {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
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cloud-files
3
- Version: 4.24.2
3
+ Version: 4.26.0
4
4
  Summary: Fast access to cloud storage and local FS.
5
5
  Home-page: https://github.com/seung-lab/cloud-files/
6
6
  Author: William Silversmith
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cloud-files
3
- Version: 4.24.2
3
+ Version: 4.26.0
4
4
  Summary: Fast access to cloud storage and local FS.
5
5
  Home-page: https://github.com/seung-lab/cloud-files/
6
6
  Author: William Silversmith
@@ -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 = [ 'graphene', 'precomputed', 'boss', 'n5' ]
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 = get_protocol(path)
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
- path = toabs(path)
154
- return f"file://{path}"
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') or 'precomputed'
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
 
@@ -11,6 +11,9 @@ setuptools.setup(
11
11
  "cloudfiles=cloudfiles_cli:main"
12
12
  ],
13
13
  },
14
+ extras_require={
15
+ "apache": [ "lxml", ],
16
+ },
14
17
  pbr=True
15
18
  )
16
19
 
@@ -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