12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758 |
- import base64
- import io
- from typing import Optional
- from urllib.parse import unquote
- from fsspec import AbstractFileSystem
- class DataFileSystem(AbstractFileSystem):
- """A handy decoder for data-URLs
- Example
- -------
- >>> with fsspec.open("data:,Hello%2C%20World%21") as f:
- ... print(f.read())
- b"Hello, World!"
- See https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URLs
- """
- protocol = "data"
- def __init__(self, **kwargs):
- """No parameters for this filesystem"""
- super().__init__(**kwargs)
- def cat_file(self, path, start=None, end=None, **kwargs):
- pref, data = path.split(",", 1)
- if pref.endswith("base64"):
- return base64.b64decode(data)[start:end]
- return unquote(data).encode()[start:end]
- def info(self, path, **kwargs):
- pref, name = path.split(",", 1)
- data = self.cat_file(path)
- mime = pref.split(":", 1)[1].split(";", 1)[0]
- return {"name": name, "size": len(data), "type": "file", "mimetype": mime}
- def _open(
- self,
- path,
- mode="rb",
- block_size=None,
- autocommit=True,
- cache_options=None,
- **kwargs,
- ):
- if "r" not in mode:
- raise ValueError("Read only filesystem")
- return io.BytesIO(self.cat_file(path))
- @staticmethod
- def encode(data: bytes, mime: Optional[str] = None):
- """Format the given data into data-URL syntax
- This version always base64 encodes, even when the data is ascii/url-safe.
- """
- return f"data:{mime or ''};base64,{base64.b64encode(data).decode()}"
|