A Python wrapper for LittleFS filesystem designed for embedded systems with minimal RAM and flash requirements
—
Direct access to LittleFS C API through Cython bindings, providing precise control over filesystem operations, configuration parameters, and block-level access patterns. This API closely mirrors the original C implementation and is suitable for embedded systems development and advanced use cases.
Core configuration and filesystem objects that represent the LittleFS state.
class LFSConfig:
def __init__(self, context=None, *, block_size: int = 128, block_count: int = 64,
read_size: int = 0, prog_size: int = 0, block_cycles: int = -1,
cache_size: int = 0, lookahead_size: int = 8, name_max: int = 255,
file_max: int = 0, attr_max: int = 0, metadata_max: int = 0,
disk_version: int = 0):
"""
LittleFS Configuration object.
Parameters:
- context: UserContext, storage backend (default: memory buffer)
- block_size: int, block size in bytes (minimum 128)
- block_count: int, number of blocks (0 to autodetect from filesystem)
- read_size: int, minimum read size (default: block_size)
- prog_size: int, minimum program size (default: block_size)
- block_cycles: int, erase cycles before wear leveling (-1 to disable)
- cache_size: int, block cache size (default: max of read_size/prog_size)
- lookahead_size: int, lookahead buffer size in bytes (must be multiple of 8)
- name_max: int, maximum filename length (default 255, max 1022)
- file_max: int, maximum file size (0 for no limit)
- attr_max: int, maximum attribute size (0 for no limit)
- metadata_max: int, maximum metadata size (0 for no limit)
- disk_version: int, disk format version (0 for default)
"""
class LFSFilesystem:
"""Low-level filesystem object representing mounted LittleFS state."""
@property
def block_count(self) -> int:
"""Number of blocks in the filesystem."""
class LFSFile:
"""Low-level file handle for opened files."""
@property
def flags(self) -> LFSFileFlag:
"""File mode flags of the opened file."""
class LFSDirectory:
"""Low-level directory handle for opened directories."""Access to LFSConfig parameters for runtime inspection.
# LFSConfig properties (read-only)
@property
def read_size(self) -> int:
"""Minimum read size in bytes."""
@property
def prog_size(self) -> int:
"""Minimum program size in bytes."""
@property
def block_size(self) -> int:
"""Block size in bytes."""
@property
def block_count(self) -> int:
"""Number of blocks in filesystem."""
@property
def cache_size(self) -> int:
"""Block cache size in bytes."""
@property
def lookahead_size(self) -> int:
"""Lookahead buffer size in bytes."""
@property
def name_max(self) -> int:
"""Maximum filename length."""
@property
def file_max(self) -> int:
"""Maximum file size (0 for no limit)."""
@property
def attr_max(self) -> int:
"""Maximum attribute size (0 for no limit)."""
@property
def metadata_max(self) -> int:
"""Maximum metadata size (0 for no limit)."""
@property
def disk_version(self) -> int:
"""Disk format version."""
@property
def user_context(self) -> UserContext:
"""Associated user context (storage backend)."""Core filesystem management functions that directly map to LittleFS C API.
def format(fs: LFSFilesystem, cfg: LFSConfig) -> int:
"""
Format the filesystem.
Parameters:
- fs: LFSFilesystem, filesystem object
- cfg: LFSConfig, configuration object
Returns:
int: 0 on success, negative error code on failure
"""
def mount(fs: LFSFilesystem, cfg: LFSConfig) -> int:
"""
Mount the filesystem.
Parameters:
- fs: LFSFilesystem, filesystem object
- cfg: LFSConfig, configuration object
Returns:
int: 0 on success, negative error code on failure
"""
def unmount(fs: LFSFilesystem) -> int:
"""
Unmount the filesystem.
Parameters:
- fs: LFSFilesystem, filesystem object
Returns:
int: 0 on success, negative error code on failure
"""
def fs_stat(fs: LFSFilesystem) -> LFSFSStat:
"""
Get filesystem status.
Parameters:
- fs: LFSFilesystem, filesystem object
Returns:
LFSFSStat: Filesystem statistics
"""
def fs_size(fs: LFSFilesystem) -> int:
"""
Get number of blocks currently in use.
Parameters:
- fs: LFSFilesystem, filesystem object
Returns:
int: Number of used blocks
"""
def fs_gc(fs: LFSFilesystem) -> int:
"""
Perform garbage collection.
Parameters:
- fs: LFSFilesystem, filesystem object
Returns:
int: 0 on success, negative error code on failure
"""
def fs_mkconsistent(fs: LFSFilesystem) -> int:
"""
Make filesystem consistent and ready for writing.
Parameters:
- fs: LFSFilesystem, filesystem object
Returns:
int: 0 on success, negative error code on failure
"""
def fs_grow(fs: LFSFilesystem, block_count: int) -> int:
"""
Grow filesystem to new size.
Parameters:
- fs: LFSFilesystem, filesystem object
- block_count: int, new number of blocks
Returns:
int: 0 on success, negative error code on failure
"""Low-level file I/O operations with direct control over flags and buffering.
def file_open(fs: LFSFilesystem, path: str, flags: Union[str, int]) -> LFSFile:
"""
Open a file.
Parameters:
- fs: LFSFilesystem, filesystem object
- path: str, file path
- flags: str or int, open flags ('r', 'w', 'a', 'x', '+') or LFSFileFlag values
Returns:
LFSFile: File handle
Raises:
LittleFSError: On open failure
"""
def file_close(fs: LFSFilesystem, fh: LFSFile) -> int:
"""
Close a file.
Parameters:
- fs: LFSFilesystem, filesystem object
- fh: LFSFile, file handle
Returns:
int: 0 on success, negative error code on failure
"""
def file_sync(fs: LFSFilesystem, fh: LFSFile) -> None:
"""
Sync file to storage.
Parameters:
- fs: LFSFilesystem, filesystem object
- fh: LFSFile, file handle
Raises:
LittleFSError: On sync failure
"""
def file_read(fs: LFSFilesystem, fh: LFSFile, size: int) -> bytes:
"""
Read from file.
Parameters:
- fs: LFSFilesystem, filesystem object
- fh: LFSFile, file handle
- size: int, number of bytes to read
Returns:
bytes: Data read (may be shorter than requested)
Raises:
LittleFSError: On read failure
"""
def file_write(fs: LFSFilesystem, fh: LFSFile, data: bytes) -> int:
"""
Write to file.
Parameters:
- fs: LFSFilesystem, filesystem object
- fh: LFSFile, file handle
- data: bytes, data to write
Returns:
int: Number of bytes written
Raises:
LittleFSError: On write failure
RuntimeError: If not all data was written
"""
def file_seek(fs: LFSFilesystem, fh: LFSFile, off: int, whence: int) -> int:
"""
Seek to position in file.
Parameters:
- fs: LFSFilesystem, filesystem object
- fh: LFSFile, file handle
- off: int, offset
- whence: int, seek reference (io.SEEK_SET, io.SEEK_CUR, io.SEEK_END)
Returns:
int: New file position
Raises:
LittleFSError: On seek failure
"""
def file_tell(fs: LFSFilesystem, fh: LFSFile) -> int:
"""
Get current file position.
Parameters:
- fs: LFSFilesystem, filesystem object
- fh: LFSFile, file handle
Returns:
int: Current file position
Raises:
LittleFSError: On error
"""
def file_truncate(fs: LFSFilesystem, fh: LFSFile, size: int) -> int:
"""
Truncate file to specified size.
Parameters:
- fs: LFSFilesystem, filesystem object
- fh: LFSFile, file handle
- size: int, new file size
Returns:
int: 0 on success, negative error code on failure
"""
def file_rewind(fs: LFSFilesystem, fh: LFSFile) -> int:
"""
Rewind file to beginning.
Parameters:
- fs: LFSFilesystem, filesystem object
- fh: LFSFile, file handle
Returns:
int: 0 on success, negative error code on failure
"""
def file_size(fs: LFSFilesystem, fh: LFSFile) -> int:
"""
Get file size.
Parameters:
- fs: LFSFilesystem, filesystem object
- fh: LFSFile, file handle
Returns:
int: File size in bytes
Raises:
LittleFSError: On error
"""Low-level directory access and iteration.
def mkdir(fs: LFSFilesystem, path: str) -> int:
"""
Create a directory.
Parameters:
- fs: LFSFilesystem, filesystem object
- path: str, directory path
Returns:
int: 0 on success, negative error code on failure
"""
def dir_open(fs: LFSFilesystem, path: str) -> LFSDirectory:
"""
Open a directory for reading.
Parameters:
- fs: LFSFilesystem, filesystem object
- path: str, directory path
Returns:
LFSDirectory: Directory handle
Raises:
LittleFSError: On open failure
"""
def dir_close(fs: LFSFilesystem, dh: LFSDirectory) -> int:
"""
Close a directory handle.
Parameters:
- fs: LFSFilesystem, filesystem object
- dh: LFSDirectory, directory handle
Returns:
int: 0 on success, negative error code on failure
"""
def dir_read(fs: LFSFilesystem, dh: LFSDirectory) -> Optional[LFSStat]:
"""
Read next directory entry.
Parameters:
- fs: LFSFilesystem, filesystem object
- dh: LFSDirectory, directory handle
Returns:
LFSStat or None: Directory entry info, None when no more entries
Raises:
LittleFSError: On read failure
"""
def dir_tell(fs: LFSFilesystem, dh: LFSDirectory) -> int:
"""
Get current directory position.
Parameters:
- fs: LFSFilesystem, filesystem object
- dh: LFSDirectory, directory handle
Returns:
int: Directory position
Raises:
LittleFSError: On error
"""
def dir_rewind(fs: LFSFilesystem, dh: LFSDirectory) -> int:
"""
Rewind directory to beginning.
Parameters:
- fs: LFSFilesystem, filesystem object
- dh: LFSDirectory, directory handle
Returns:
int: 0 on success, negative error code on failure
"""File and directory manipulation at the path level.
def remove(fs: LFSFilesystem, path: str) -> int:
"""
Remove a file or empty directory.
Parameters:
- fs: LFSFilesystem, filesystem object
- path: str, path to remove
Returns:
int: 0 on success, negative error code on failure
"""
def rename(fs: LFSFilesystem, oldpath: str, newpath: str) -> int:
"""
Rename or move a file or directory.
Parameters:
- fs: LFSFilesystem, filesystem object
- oldpath: str, current path
- newpath: str, new path
Returns:
int: 0 on success, negative error code on failure
"""
def stat(fs: LFSFilesystem, path: str) -> LFSStat:
"""
Get file or directory status.
Parameters:
- fs: LFSFilesystem, filesystem object
- path: str, path to examine
Returns:
LFSStat: Status information
Raises:
LittleFSError: On stat failure
"""Low-level attribute operations for metadata storage.
def getattr(fs: LFSFilesystem, path: str, typ: int) -> bytes:
"""
Get extended attribute.
Parameters:
- fs: LFSFilesystem, filesystem object
- path: str, file or directory path
- typ: int, attribute type (0-255)
Returns:
bytes: Attribute data
Raises:
LittleFSError: On failure
"""
def setattr(fs: LFSFilesystem, path: str, typ: int, data: bytes) -> None:
"""
Set extended attribute.
Parameters:
- fs: LFSFilesystem, filesystem object
- path: str, file or directory path
- typ: int, attribute type (0-255)
- data: bytes, attribute data
Raises:
LittleFSError: On failure
"""
def removeattr(fs: LFSFilesystem, path: str, typ: int) -> None:
"""
Remove extended attribute.
Parameters:
- fs: LFSFilesystem, filesystem object
- path: str, file or directory path
- typ: int, attribute type (0-255)
Raises:
LittleFSError: On failure
"""__LFS_VERSION__: Tuple[int, int] # LittleFS library version
__LFS_DISK_VERSION__: Tuple[int, int] # LittleFS disk format version
FILENAME_ENCODING: str = 'ascii' # Default filename encodingfrom littlefs import lfs
# Create configuration and filesystem objects
cfg = lfs.LFSConfig(block_size=512, block_count=256)
fs = lfs.LFSFilesystem()
# Format and mount
lfs.format(fs, cfg)
lfs.mount(fs, cfg)
# Create a file and write data
fh = lfs.file_open(fs, 'test.txt', 'w')
lfs.file_write(fs, fh, b'Hello, World!')
lfs.file_close(fs, fh)
# Read the file back
fh = lfs.file_open(fs, 'test.txt', 'r')
data = lfs.file_read(fs, fh, 1024)
lfs.file_close(fs, fh)
print(data) # b'Hello, World!'
# Clean up
lfs.unmount(fs)# Create some files and directories
lfs.mkdir(fs, 'data')
fh = lfs.file_open(fs, 'data/file1.txt', 'w')
lfs.file_write(fs, fh, b'content1')
lfs.file_close(fs, fh)
# Iterate through directory
dh = lfs.dir_open(fs, 'data')
while True:
entry = lfs.dir_read(fs, dh)
if entry is None:
break
if entry.name not in ['.', '..']:
print(f"{entry.name}: type={entry.type}, size={entry.size}")
lfs.dir_close(fs, dh)from littlefs.context import UserContext
# Custom context with specific buffer size
ctx = UserContext(buffsize=1024*1024) # 1MB buffer
# Advanced configuration
cfg = lfs.LFSConfig(
context=ctx,
block_size=4096,
block_count=256,
read_size=256,
prog_size=256,
block_cycles=500,
cache_size=1024,
lookahead_size=32,
name_max=255
)
fs = lfs.LFSFilesystem()
lfs.format(fs, cfg)
lfs.mount(fs, cfg)
# Check filesystem statistics
stat = lfs.fs_stat(fs)
print(f"Block size: {stat.block_size}")
print(f"Block count: {stat.block_count}")
print(f"Used blocks: {lfs.fs_size(fs)}")Install with Tessl CLI
npx tessl i tessl/pypi-littlefs-python