Pluggable IO with unified interfaces.
pygx.io defines abstract FileSystem and File interfaces, plus a
Sequence abstraction for append-only line-by-line streams. Implementations
include:
- An in-memory backend (
MemoryFile, MemoryFileSystem, MemorySequence)
useful for tests and ephemeral fixtures.
- A
fsspec bridge (FsspecFile,
FsspecFileSystem) that delegates to any filesystem registered with fsspec
(local, GCS, S3, etc.).
- A line-based sequence type (
LineSequence, LineSequenceIO) used by JSONL
serialization in pg.open_jsonl.
External code can register additional FileSystem implementations and have
the rest of PyGX (save/load/open_jsonl) pick them up transparently.
File
Interface for a file.
read
abstractmethod
read(size: int | None = None) -> str | bytes
Reads the content of the file.
Source code in pygx/io/_file_system.py
| @abc.abstractmethod
def read(self, size: int | None = None) -> str | bytes:
"""Reads the content of the file."""
|
readline
abstractmethod
readline() -> str | bytes
Reads the next line.
Source code in pygx/io/_file_system.py
| @abc.abstractmethod
def readline(self) -> str | bytes:
"""Reads the next line."""
|
write
abstractmethod
write(content: str | bytes) -> None
Writes the content of the file.
Source code in pygx/io/_file_system.py
| @abc.abstractmethod
def write(self, content: str | bytes) -> None:
"""Writes the content of the file."""
|
seek
abstractmethod
seek(offset: int, whence: Literal[0, 1, 2] = 0) -> int
Changes the current position of the file.
Parameters:
| Name |
Type |
Description |
Default |
offset
|
int
|
Offset from the position to a reference point.
|
required
|
whence
|
Literal[0, 1, 2]
|
The reference point, with 0 meaning the beginning of the file,
1 meaning the current position, or 2 meaning the end of the file.
|
0
|
Returns:
| Type |
Description |
int
|
The position from the beginning of the file.
|
Source code in pygx/io/_file_system.py
| @abc.abstractmethod
def seek(self, offset: int, whence: Literal[0, 1, 2] = 0) -> int:
"""Changes the current position of the file.
Args:
offset: Offset from the position to a reference point.
whence: The reference point, with 0 meaning the beginning of the file,
1 meaning the current position, or 2 meaning the end of the file.
Returns:
The position from the beginning of the file.
"""
|
tell
abstractmethod
Returns the current position of the file.
Source code in pygx/io/_file_system.py
| @abc.abstractmethod
def tell(self) -> int:
"""Returns the current position of the file."""
|
flush
abstractmethod
Flushes the written content to the storage.
Source code in pygx/io/_file_system.py
| @abc.abstractmethod
def flush(self) -> None:
"""Flushes the written content to the storage."""
|
close
abstractmethod
Closes the file.
Source code in pygx/io/_file_system.py
| @abc.abstractmethod
def close(self) -> None:
"""Closes the file."""
|
FileSystem
Interface for a file system.
open
abstractmethod
open(path: str | PathLike[str], mode: str = 'r', **kwargs) -> File
Opens a file with a path.
Source code in pygx/io/_file_system.py
| @abc.abstractmethod
def open(
self, path: str | os.PathLike[str], mode: str = 'r', **kwargs
) -> File:
"""Opens a file with a path."""
|
chmod
abstractmethod
chmod(path: str | PathLike[str], mode: int) -> None
Changes the permission of a file.
Source code in pygx/io/_file_system.py
| @abc.abstractmethod
def chmod(self, path: str | os.PathLike[str], mode: int) -> None:
"""Changes the permission of a file."""
|
exists
abstractmethod
exists(path: str | PathLike[str]) -> bool
Returns True if a path exists.
Source code in pygx/io/_file_system.py
| @abc.abstractmethod
def exists(self, path: str | os.PathLike[str]) -> bool:
"""Returns True if a path exists."""
|
glob
abstractmethod
glob(pattern: str | PathLike[str]) -> list[str]
Lists all files or sub-directories.
Source code in pygx/io/_file_system.py
| @abc.abstractmethod
def glob(self, pattern: str | os.PathLike[str]) -> list[str]:
"""Lists all files or sub-directories."""
|
listdir
abstractmethod
listdir(path: str | PathLike[str]) -> list[str]
Lists all files or sub-directories.
Source code in pygx/io/_file_system.py
| @abc.abstractmethod
def listdir(self, path: str | os.PathLike[str]) -> list[str]:
"""Lists all files or sub-directories."""
|
isdir
abstractmethod
isdir(path: str | PathLike[str]) -> bool
Returns True if a path is a directory.
Source code in pygx/io/_file_system.py
| @abc.abstractmethod
def isdir(self, path: str | os.PathLike[str]) -> bool:
"""Returns True if a path is a directory."""
|
getctime
abstractmethod
getctime(path: str | PathLike[str]) -> float
Returns the creation time of a file.
Source code in pygx/io/_file_system.py
| @abc.abstractmethod
def getctime(self, path: str | os.PathLike[str]) -> float:
"""Returns the creation time of a file."""
|
getmtime
abstractmethod
getmtime(path: str | PathLike[str]) -> float
Returns the last modification time of a file.
Source code in pygx/io/_file_system.py
| @abc.abstractmethod
def getmtime(self, path: str | os.PathLike[str]) -> float:
"""Returns the last modification time of a file."""
|
mkdir
abstractmethod
mkdir(path: str | PathLike[str], mode: int = 511) -> None
Makes a directory based on a path.
Source code in pygx/io/_file_system.py
| @abc.abstractmethod
def mkdir(self, path: str | os.PathLike[str], mode: int = 0o777) -> None:
"""Makes a directory based on a path."""
|
mkdirs
abstractmethod
mkdirs(
path: str | PathLike[str], mode: int = 511, exist_ok: bool = True
) -> None
Makes a directory chain based on a path.
Source code in pygx/io/_file_system.py
| @abc.abstractmethod
def mkdirs(
self,
path: str | os.PathLike[str],
mode: int = 0o777,
exist_ok: bool = True,
) -> None:
"""Makes a directory chain based on a path."""
|
rm
abstractmethod
rm(path: str | PathLike[str]) -> None
Removes a file based on a path.
Source code in pygx/io/_file_system.py
| @abc.abstractmethod
def rm(self, path: str | os.PathLike[str]) -> None:
"""Removes a file based on a path."""
|
rename
abstractmethod
rename(oldpath: str | PathLike[str], newpath: str | PathLike[str]) -> None
Renames a file based on a path.
Source code in pygx/io/_file_system.py
| @abc.abstractmethod
def rename(
self,
oldpath: str | os.PathLike[str],
newpath: str | os.PathLike[str],
) -> None:
"""Renames a file based on a path."""
|
rmdir
abstractmethod
rmdir(path: str | PathLike[str]) -> None
Removes a directory based on a path.
Source code in pygx/io/_file_system.py
| @abc.abstractmethod
def rmdir(self, path: str | os.PathLike[str]) -> None:
"""Removes a directory based on a path."""
|
rmdirs
abstractmethod
rmdirs(path: str | PathLike[str]) -> None
Removes a directory chain based on a path.
Source code in pygx/io/_file_system.py
| @abc.abstractmethod
def rmdirs(self, path: str | os.PathLike[str]) -> None:
"""Removes a directory chain based on a path."""
|
copy
abstractmethod
copy(oldpath: str | PathLike[str], newpath: str | PathLike[str]) -> None
Copies a file to a new path.
Source code in pygx/io/_file_system.py
| @abc.abstractmethod
def copy(
self,
oldpath: str | os.PathLike[str],
newpath: str | os.PathLike[str],
) -> None:
"""Copies a file to a new path."""
|
StdFile
StdFile(file_object, path: str | PathLike[str])
Bases: File
The standard file.
Source code in pygx/io/_file_system.py
| def __init__(self, file_object, path: str | os.PathLike[str]) -> None:
super().__init__()
self._file_object = file_object
self._path = path
|
StdFileSystem
Bases: FileSystem
The standard file system.
MemoryFile
MemoryFile(buffer: IOBase)
Bases: File
Memory file.
Source code in pygx/io/_file_system.py
| def __init__(self, buffer: io.IOBase):
super().__init__()
self._buffer = buffer
self._pos = 0
now = datetime.datetime.now().timestamp()
self.ctime = now
self.mtime = now
|
MemoryFileSystem
MemoryFileSystem(prefix: str = '/mem/')
Bases: FileSystem
The in-memory file system.
Source code in pygx/io/_file_system.py
| def __init__(self, prefix: str = '/mem/'):
super().__init__()
self._root = {}
self._prefix = prefix
|
getctime
getctime(path: str | PathLike[str]) -> float
Returns the creation time of a file.
Source code in pygx/io/_file_system.py
| def getctime(self, path: str | os.PathLike[str]) -> float:
"""Returns the creation time of a file."""
f = self._locate(path)
if isinstance(f, dict):
raise IsADirectoryError(path)
if f is None:
raise FileNotFoundError(path)
return f.ctime
|
getmtime
getmtime(path: str | PathLike[str]) -> float
Returns the last modification time of a file.
Source code in pygx/io/_file_system.py
| def getmtime(self, path: str | os.PathLike[str]) -> float:
"""Returns the last modification time of a file."""
f = self._locate(path)
if isinstance(f, dict):
raise IsADirectoryError(path)
if f is None:
raise FileNotFoundError(path)
return f.mtime
|
FsspecFile
Bases: File
File object based on fsspec.
Source code in pygx/io/_file_system.py
| def __init__(self, f):
self._f = f
|
FsspecFileSystem
Bases: FileSystem
File system based on fsspec.
Sequence
Sequence(
perms: int | None = None,
serializer: Callable[[Any], bytes | str] | None = None,
deserializer: Callable[[bytes | str], Any] | None = None,
)
Interface for a sequence of records.
Source code in pygx/io/_sequence.py
| def __init__(
self,
perms: int | None = None,
serializer: Callable[[Any], bytes | str] | None = None,
deserializer: Callable[[bytes | str], Any] | None = None,
):
self._perms = perms
self._serializer = serializer
self._deserializer = deserializer
|
add
Adds a record to the reader.
Source code in pygx/io/_sequence.py
| def add(self, record: Any) -> None:
"""Adds a record to the reader."""
if self._serializer:
record = self._serializer(record)
if not isinstance(record, (str, bytes)):
raise ValueError(
f'Cannot write record with type {type(record)}. '
'Did you forget to pass a serializer?'
)
self._add(record)
|
close
abstractmethod
Closes the reader.
Source code in pygx/io/_sequence.py
| @abc.abstractmethod
def close(self) -> None:
"""Closes the reader."""
|
flush
abstractmethod
Flushes the read records to the storage.
Source code in pygx/io/_sequence.py
| @abc.abstractmethod
def flush(self) -> None:
"""Flushes the read records to the storage."""
|
SequenceIO
Interface for a record IO system.
open
abstractmethod
open(
path: str | PathLike[str],
mode: str,
*,
perms: int | None,
serializer: Callable[[Any], bytes | str] | None,
deserializer: Callable[[bytes | str], Any] | None,
**kwargs
) -> Sequence
Opens a sequence for reading or writing.
Source code in pygx/io/_sequence.py
| @abc.abstractmethod
def open(
self,
path: str | os.PathLike[str],
mode: str,
*,
perms: int | None,
serializer: Callable[[Any], bytes | str] | None,
deserializer: Callable[[bytes | str], Any] | None,
**kwargs,
) -> Sequence:
"""Opens a sequence for reading or writing."""
|
MemorySequence
MemorySequence(
path: str | PathLike[str],
mode: str,
records: list[str | bytes],
*,
perms: int | None,
serializer: Callable[[Any], bytes | str] | None,
deserializer: Callable[[bytes | str], Any] | None
)
Bases: Sequence
An in-memory sequence.
Source code in pygx/io/_sequence.py
| def __init__(
self,
path: str | os.PathLike[str],
mode: str,
records: list[str | bytes],
*,
perms: int | None,
serializer: Callable[[Any], bytes | str] | None,
deserializer: Callable[[bytes | str], Any] | None,
):
super().__init__(perms, serializer, deserializer)
self._path = path
self._mode = mode
self._records = records
self._closed = False
|
MemorySequenceIO
Bases: SequenceIO
Memory-based record IO.
Source code in pygx/io/_sequence.py
| def __init__(self):
super().__init__()
self._root = collections.defaultdict(list)
|
open
open(
path: str | PathLike[str],
mode: str,
*,
perms: int | None,
serializer: Callable[[Any], bytes | str] | None,
deserializer: Callable[[bytes | str], Any] | None,
**kwargs
) -> Sequence
Opens a reader for a sequence.
Source code in pygx/io/_sequence.py
| def open(
self,
path: str | os.PathLike[str],
mode: str,
*,
perms: int | None,
serializer: Callable[[Any], bytes | str] | None,
deserializer: Callable[[bytes | str], Any] | None,
**kwargs,
) -> Sequence:
"""Opens a reader for a sequence."""
del kwargs
if 'w' in mode:
self._root[path] = []
return MemorySequence(
path,
mode,
self._root[path],
perms=perms,
serializer=serializer,
deserializer=deserializer,
)
|
LineSequence
LineSequence(
path: str | PathLike[str],
mode: str,
perms: int | None,
serializer: Callable[[Any], bytes | str] | None,
deserializer: Callable[[bytes | str], Any] | None,
)
Bases: Sequence
A new-line broken sequence.
Source code in pygx/io/_sequence.py
| def __init__(
self,
path: str | os.PathLike[str],
mode: str,
perms: int | None,
serializer: Callable[[Any], bytes | str] | None,
deserializer: Callable[[bytes | str], Any] | None,
) -> None:
super().__init__(perms, serializer, deserializer)
self._path = path
self._mode = mode
self._file = file_system.open(path, mode)
|
LineSequenceIO
Bases: SequenceIO
Line-based record IO.
open
open(
path: str | PathLike[str],
mode: str,
*,
perms: int | None,
serializer: Callable[[Any], bytes | str] | None,
deserializer: Callable[[bytes | str], Any] | None,
**kwargs
) -> Sequence
Opens a reader for a sequence.
Source code in pygx/io/_sequence.py
| def open(
self,
path: str | os.PathLike[str],
mode: str,
*,
perms: int | None,
serializer: Callable[[Any], bytes | str] | None,
deserializer: Callable[[bytes | str], Any] | None,
**kwargs,
) -> Sequence:
"""Opens a reader for a sequence."""
del kwargs
return LineSequence(path, mode, perms, serializer, deserializer)
|
add_file_system
add_file_system(prefix: str, fs: FileSystem) -> None
Adds a file system with a prefix.
Source code in pygx/io/_file_system.py
| def add_file_system(prefix: str, fs: FileSystem) -> None:
"""Adds a file system with a prefix."""
_fs.add(prefix, fs)
|
open
open(path: str | PathLike[str], mode: str = 'r', **kwargs) -> File
Opens a file with a path.
Source code in pygx/io/_file_system.py
| def open(path: str | os.PathLike[str], mode: str = 'r', **kwargs) -> File: # pylint:disable=redefined-builtin
"""Opens a file with a path."""
return _fs.get(path).open(path, mode, **kwargs)
|
chmod
chmod(path: str | PathLike[str], mode: int) -> None
Changes the permission of a file.
Source code in pygx/io/_file_system.py
| def chmod(path: str | os.PathLike[str], mode: int) -> None:
"""Changes the permission of a file."""
_fs.get(path).chmod(path, mode)
|
readfile
readfile(
path: str | PathLike[str],
mode: str = "r",
nonexist_ok: bool = False,
**kwargs
) -> bytes | str | None
Reads content from a file.
Source code in pygx/io/_file_system.py
| def readfile(
path: str | os.PathLike[str],
mode: str = 'r',
nonexist_ok: bool = False,
**kwargs,
) -> bytes | str | None:
"""Reads content from a file."""
try:
with _fs.get(path).open(path, mode=mode, **kwargs) as f:
return f.read()
except FileNotFoundError as e:
if nonexist_ok:
return None
raise e
|
writefile
writefile(
path: str | PathLike[str],
content: str | bytes,
*,
mode: str = "w",
perms: int | None = 436,
**kwargs
) -> None
Writes content to a file.
Source code in pygx/io/_file_system.py
| def writefile(
path: str | os.PathLike[str],
content: str | bytes,
*,
mode: str = 'w',
perms: int | None = 0o664, # Default to world-readable.
**kwargs,
) -> None:
"""Writes content to a file."""
with _fs.get(path).open(path, mode=mode, **kwargs) as f:
f.write(content)
if perms is not None:
chmod(path, perms)
|
rename
rename(oldpath: str | PathLike[str], newpath: str | PathLike[str]) -> None
Renames a file.
Source code in pygx/io/_file_system.py
| def rename(
oldpath: str | os.PathLike[str],
newpath: str | os.PathLike[str],
) -> None:
"""Renames a file."""
_fs.get(oldpath).rename(oldpath, newpath)
|
rm
rm(path: str | PathLike[str]) -> None
Removes a file.
Source code in pygx/io/_file_system.py
| def rm(path: str | os.PathLike[str]) -> None:
"""Removes a file."""
_fs.get(path).rm(path)
|
copy
copy(oldpath: str | PathLike[str], newpath: str | PathLike[str]) -> None
Copies a file.
Source code in pygx/io/_file_system.py
| def copy(
oldpath: str | os.PathLike[str],
newpath: str | os.PathLike[str],
) -> None:
"""Copies a file."""
_fs.get(oldpath).copy(oldpath, newpath)
|
path_exists
path_exists(path: str | PathLike[str]) -> bool
Returns True if path exists.
Source code in pygx/io/_file_system.py
| def path_exists(path: str | os.PathLike[str]) -> bool:
"""Returns True if path exists."""
return _fs.get(path).exists(path)
|
glob
glob(pattern: str | PathLike[str]) -> list[str]
Lists all files or sub-directories.
Source code in pygx/io/_file_system.py
| def glob(pattern: str | os.PathLike[str]) -> list[str]:
"""Lists all files or sub-directories."""
return _fs.get(pattern).glob(pattern)
|
listdir
listdir(path: str | PathLike[str], fullpath: bool = False) -> list[str]
Lists all files or sub-directories under a dir.
Source code in pygx/io/_file_system.py
| def listdir(path: str | os.PathLike[str], fullpath: bool = False) -> list[str]: # pylint: disable=redefined-builtin
"""Lists all files or sub-directories under a dir."""
entries = _fs.get(path).listdir(path)
if fullpath:
return [os.path.join(path, entry) for entry in entries]
return entries
|
isdir
isdir(path: str | PathLike[str]) -> bool
Returns True if path is a directory.
Source code in pygx/io/_file_system.py
| def isdir(path: str | os.PathLike[str]) -> bool:
"""Returns True if path is a directory."""
return _fs.get(path).isdir(path)
|
getctime
getctime(path: str | PathLike[str]) -> float
Returns the creation time of a file.
Source code in pygx/io/_file_system.py
| def getctime(path: str | os.PathLike[str]) -> float:
"""Returns the creation time of a file."""
return _fs.get(path).getctime(path)
|
getmtime
getmtime(path: str | PathLike[str]) -> float
Returns the last modification time of a file.
Source code in pygx/io/_file_system.py
| def getmtime(path: str | os.PathLike[str]) -> float:
"""Returns the last modification time of a file."""
return _fs.get(path).getmtime(path)
|
mkdir
mkdir(path: str | PathLike[str], mode: int = 511) -> None
Makes a directory.
Source code in pygx/io/_file_system.py
| def mkdir(path: str | os.PathLike[str], mode: int = 0o777) -> None:
"""Makes a directory."""
_fs.get(path).mkdir(path, mode=mode)
|
mkdirs
mkdirs(
path: str | PathLike[str], mode: int = 511, exist_ok: bool = True
) -> None
Makes a directory chain.
Source code in pygx/io/_file_system.py
| def mkdirs(
path: str | os.PathLike[str],
mode: int = 0o777,
exist_ok: bool = True,
) -> None:
"""Makes a directory chain."""
_fs.get(path).mkdirs(path, mode=mode, exist_ok=exist_ok)
|
rmdir
rmdir(path: str | PathLike[str]) -> None
Removes a directory.
Source code in pygx/io/_file_system.py
| def rmdir(path: str | os.PathLike[str]) -> None:
"""Removes a directory."""
_fs.get(path).rmdir(path)
|
rmdirs
rmdirs(path: str | PathLike[str]) -> None
Removes a directory chain until a parent directory is not empty.
Source code in pygx/io/_file_system.py
| def rmdirs(path: str | os.PathLike[str]) -> None:
"""Removes a directory chain until a parent directory is not empty."""
_fs.get(path).rmdirs(path)
|
add_sequence_io
add_sequence_io(extension: str, sequence_io: SequenceIO) -> None
Adds a record IO system with a prefix.
Source code in pygx/io/_sequence.py
| def add_sequence_io(extension: str, sequence_io: SequenceIO) -> None:
"""Adds a record IO system with a prefix."""
_registry.add(extension, sequence_io)
|
open_sequence
open_sequence(
path: str | PathLike[str],
mode: str = "r",
*,
perms: int | None = 436,
serializer: Callable[[Any], bytes | str] | None = None,
deserializer: Callable[[bytes | str], Any] | None = None,
make_dirs_if_not_exist: bool = True
) -> Sequence
Open sequence for reading or writing.
Parameters:
| Name |
Type |
Description |
Default |
path
|
str | PathLike[str]
|
The path to the sequence.
|
required
|
mode
|
str
|
The mode of the sequence.
|
'r'
|
perms
|
int | None
|
(Optional) The permissions of the sequence.
|
436
|
serializer
|
Callable[[Any], bytes | str] | None
|
(Optional) A serializer function for converting a structured
object to a string or bytes.
|
None
|
deserializer
|
Callable[[bytes | str], Any] | None
|
(Optional) A deserializer function for converting a string or
bytes to a structured object.
|
None
|
make_dirs_if_not_exist
|
bool
|
(Optional) Whether to create the directories
if they do not exist. Applicable when opening in write or append mode.
|
True
|
Returns:
| Type |
Description |
Sequence
|
A sequence for reading or writing.
|
Source code in pygx/io/_sequence.py
| def open_sequence(
path: str | os.PathLike[str],
mode: str = 'r',
*,
perms: int | None = 0o664, # Default to world-readable.
serializer: Callable[[Any], bytes | str] | None = None,
deserializer: Callable[[bytes | str], Any] | None = None,
make_dirs_if_not_exist: bool = True,
) -> Sequence:
"""Open sequence for reading or writing.
Args:
path: The path to the sequence.
mode: The mode of the sequence.
perms: (Optional) The permissions of the sequence.
serializer: (Optional) A serializer function for converting a structured
object to a string or bytes.
deserializer: (Optional) A deserializer function for converting a string or
bytes to a structured object.
make_dirs_if_not_exist: (Optional) Whether to create the directories
if they do not exist. Applicable when opening in write or append mode.
Returns:
A sequence for reading or writing.
"""
if 'w' in mode or 'a' in mode:
parent_dir = os.path.dirname(path)
if make_dirs_if_not_exist:
file_system.mkdirs(parent_dir, exist_ok=True)
return _registry.get(path).open(
path,
mode,
perms=perms,
serializer=serializer,
deserializer=deserializer,
)
|