Skip to content

Commit 62d5e46

Browse files
authored
Merge pull request #9 from martindurant/apps-demo
Changes to allow running on pyscriptapps proxy
2 parents fa8c27d + 0bf24e6 commit 62d5e46

File tree

1 file changed

+50
-45
lines changed
  • pyscript-fsspec-client/pyscript_fsspec_client

1 file changed

+50
-45
lines changed
Lines changed: 50 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,63 @@
1+
"""An fsspec filesystem that proxies via pyscriptapps.com."""
2+
13
from json import dumps, loads
24
import logging
3-
import os
45

56
from pyscript import sync, ffi
67
from fsspec.spec import AbstractFileSystem, AbstractBufferedFile
78
import fsspec.utils
89

910
logger = logging.getLogger("pyscript_fsspec_client")
1011
fsspec.utils.setup_logging(logger=logger)
11-
default_endpoint = os.getenv("FSSPEC_PROXY_URL", "http://127.0.0.1:8000")
1212

1313

1414
class PyscriptFileSystem(AbstractFileSystem):
15+
"""An fsspec filesystem that proxies via pyscriptapps.com."""
16+
1517
protocol = "pyscript"
1618

17-
def __init__(self, base_url=default_endpoint):
19+
def __init__(self, base_url):
1820
super().__init__()
1921
self.base_url = base_url
2022

21-
def _split_path(self, path):
22-
key, *relpath = path.split("/", 1)
23-
return key, relpath[0] if relpath else ""
23+
# `AbstractFileSystem` protocol ############################################
24+
25+
def cat_file(self, path, start=None, end=None, **kw):
26+
if start is not None and end is not None:
27+
range = (start, end + 1)
28+
else:
29+
range = None
30+
return self._call(f"bytes/{path}", binary=True, range=range)
31+
32+
def ls(self, path, detail=True, **kwargs):
33+
path = self._strip_protocol(path)
34+
out = loads(self._call(f"list/{path}"))["contents"]
35+
36+
if detail:
37+
return out
38+
return sorted(_["name"] for _ in out)
39+
40+
def pipe_file(self, path, value, mode="overwrite", **kwargs):
41+
self._call(f"bytes/{path}", method="POST", data=value)
42+
43+
def rm_file(self, path):
44+
path = self._strip_protocol(path)
45+
self._call(f"delete/{path}", method="DELETE", binary=True)
46+
47+
def _open(
48+
self,
49+
path,
50+
mode="rb",
51+
block_size=None,
52+
autocommit=True,
53+
cache_options=None,
54+
**kwargs,
55+
):
56+
return JFile(
57+
self, path, mode, block_size, autocommit, cache_options, **kwargs
58+
)
59+
60+
# Internal #################################################################
2461

2562
def _call(self, path, method="GET", range=None, binary=False, data=0, json=0):
2663
logger.debug("request: %s %s %s", path, method, range)
@@ -47,49 +84,16 @@ def _call(self, path, method="GET", range=None, binary=False, data=0, json=0):
4784
out = bytes(out.to_py())
4885
return out
4986

50-
def ls(self, path, detail=True, **kwargs):
51-
path = self._strip_protocol(path)
52-
key, *path = path.split("/", 1)
53-
if key:
54-
part = path[0] if path else ""
55-
out = loads(self._call(f"{key}/list/{part}"))["contents"]
56-
else:
57-
raise ValueError
58-
59-
if detail:
60-
return out
61-
return sorted(_["name"] for _ in out)
62-
63-
def rm_file(self, path):
64-
path = self._strip_protocol(path)
65-
key, path = path.split("/", 1)
66-
self._call(f"{key}/delete/{path}", method="DELETE", binary=True)
67-
68-
def _open(
69-
self,
70-
path,
71-
mode="rb",
72-
block_size=None,
73-
autocommit=True,
74-
cache_options=None,
75-
**kwargs,
76-
):
77-
return JFile(self, path, mode, block_size, autocommit, cache_options, **kwargs)
87+
def _split_path(self, path):
88+
key, *relpath = path.split("/", 1)
89+
return key, relpath[0] if relpath else ""
7890

79-
def cat_file(self, path, start=None, end=None, **kw):
80-
key, relpath = self._split_path(path)
81-
if start is not None and end is not None:
82-
range = (start, end + 1)
83-
else:
84-
range = None
85-
return self._call(f"{key}/bytes/{relpath}", binary=True, range=range)
8691

87-
def pipe_file(self, path, value, mode="overwrite", **kwargs):
88-
key, relpath = self._split_path(path)
89-
self._call(f"{key}/bytes/{relpath}", method="POST", data=value)
92+
class JFile(AbstractBufferedFile):
93+
"""An fsspec buffered file implementation for the `pyscript` protocol."""
9094

95+
# `AbstractBufferedFile` protocol ##########################################
9196

92-
class JFile(AbstractBufferedFile):
9397
def _fetch_range(self, start, end):
9498
return self.fs.cat_file(self.path, start, end)
9599

@@ -99,4 +103,5 @@ def _upload_chunk(self, final=False):
99103
return True
100104
return False
101105

106+
102107
fsspec.register_implementation("pyscript", PyscriptFileSystem)

0 commit comments

Comments
 (0)