0
# fuse-python
1
2
Python bindings for FUSE (Filesystem in USErspace) that enable developers to create custom filesystems running in user space. The library provides a comprehensive interface to libfuse functionality, allowing implementation of virtual filesystems with full POSIX filesystem operation support including file I/O, directory operations, metadata handling, and advanced features like extended attributes and file locking.
3
4
## Package Information
5
6
- **Package Name**: fuse-python
7
- **Language**: Python
8
- **Installation**: `pip install fuse-python`
9
- **Repository**: https://github.com/libfuse/python-fuse
10
11
## Core Imports
12
13
```python
14
import fuse
15
from fuse import Fuse
16
```
17
18
Essential exception handling:
19
20
```python
21
from fuse import FuseError
22
```
23
24
Set API version (recommended):
25
26
```python
27
fuse.fuse_python_api = (0, 2)
28
```
29
30
Advanced imports (for low-level operations):
31
32
```python
33
from fuse import FuseGetContext, FuseInvalidate, FuseNotifyPoll
34
from fuse import APIVersion, feature_needs, feature_assert
35
```
36
37
## Basic Usage
38
39
```python
40
import fuse
41
from fuse import Fuse
42
import stat
43
import errno
44
45
# Set API version
46
fuse.fuse_python_api = (0, 2)
47
48
class HelloFS(Fuse):
49
"""Simple filesystem that shows a single file."""
50
51
def getattr(self, path):
52
"""Get file/directory attributes."""
53
st = fuse.Stat()
54
if path == '/':
55
st.st_mode = stat.S_IFDIR | 0o755
56
st.st_nlink = 2
57
elif path == '/hello':
58
st.st_mode = stat.S_IFREG | 0o444
59
st.st_nlink = 1
60
st.st_size = 13
61
else:
62
return -errno.ENOENT
63
return st
64
65
def readdir(self, path, offset):
66
"""Read directory contents."""
67
for r in '.', '..', 'hello':
68
yield fuse.Direntry(r)
69
70
def read(self, path, size, offset):
71
"""Read file content."""
72
if path != '/hello':
73
return -errno.ENOENT
74
content = b'Hello World!\n'
75
return content[offset:offset+size]
76
77
# Create and run filesystem
78
fs = HelloFS(version="HelloFS 1.0")
79
fs.parse()
80
fs.main()
81
```
82
83
## Architecture
84
85
fuse-python uses a class-based architecture where filesystem implementations inherit from the `Fuse` base class:
86
87
- **Fuse Class**: Main interface class that handles FUSE protocol communication and dispatches filesystem operations
88
- **Data Structures**: Dedicated classes for system structures (`Stat`, `StatVfs`, `Direntry`, etc.)
89
- **Command Line Processing**: Integrated argument parsing with `FuseArgs` and `FuseOptParse`
90
- **C Extension**: Low-level `fuseparts._fuse` module provides the FUSE library interface
91
- **Error Handling**: Standard errno-based error reporting with exception support
92
93
## Capabilities
94
95
### Core Filesystem Operations
96
97
Essential filesystem operations that must be implemented for basic functionality, including file and directory attribute retrieval, directory listing, and file content operations.
98
99
```python { .api }
100
def getattr(self, path):
101
"""Get file/directory attributes. Returns Stat object or negative errno."""
102
103
def readdir(self, path, offset):
104
"""Read directory contents. Yields Direntry objects."""
105
106
def read(self, path, size, offset):
107
"""Read file content. Returns bytes or negative errno."""
108
109
def write(self, path, buf, offset):
110
"""Write file content. Returns bytes written or negative errno."""
111
```
112
113
[Core Operations](./core-operations.md)
114
115
### File and Directory Management
116
117
Operations for creating, removing, and modifying files and directories, including symbolic links and permission changes.
118
119
```python { .api }
120
def mknod(self, path, mode, dev):
121
"""Create a file node. Returns 0 on success or negative errno."""
122
123
def mkdir(self, path, mode):
124
"""Create directory. Returns 0 on success or negative errno."""
125
126
def unlink(self, path):
127
"""Remove file. Returns 0 on success or negative errno."""
128
129
def rmdir(self, path):
130
"""Remove directory. Returns 0 on success or negative errno."""
131
```
132
133
[File Management](./file-management.md)
134
135
### Data Structures and Types
136
137
FUSE data structures for representing file attributes, directory entries, and other filesystem metadata.
138
139
```python { .api }
140
class Stat:
141
"""File/directory attributes."""
142
st_mode: int
143
st_ino: int
144
st_size: int
145
st_atime: int
146
st_mtime: int
147
st_ctime: int
148
149
class Direntry:
150
"""Directory entry."""
151
name: str
152
type: int
153
ino: int
154
offset: int
155
```
156
157
[Data Structures](./data-structures.md)
158
159
### Command Line and Configuration
160
161
Integrated command line argument processing and FUSE option management for filesystem mounting and configuration.
162
163
```python { .api }
164
class FuseArgs:
165
"""FUSE command line arguments."""
166
mountpoint: str
167
modifiers: dict
168
169
def parse(self, *args, **kwargs):
170
"""Parse command line arguments."""
171
172
def main(self):
173
"""Enter filesystem service loop."""
174
```
175
176
[Configuration](./configuration.md)
177
178
### Extended Features
179
180
Advanced FUSE features including extended attributes, file locking, access control, and filesystem statistics.
181
182
```python { .api }
183
def getxattr(self, path, name, size):
184
"""Get extended attribute value."""
185
186
def setxattr(self, path, name, val, flags):
187
"""Set extended attribute value."""
188
189
def access(self, path, mode):
190
"""Check file access permissions."""
191
192
def lock(self, path, fip, cmd, lock):
193
"""File locking operations."""
194
```
195
196
[Extended Features](./extended-features.md)
197
198
## Error Handling
199
200
All filesystem operations should return appropriate errno values for errors:
201
202
- Return negative errno values (e.g., `-errno.ENOENT`) for errors
203
- Return 0 or positive values for success
204
- Alternatively, raise `OSError` or `IOError` exceptions
205
- Use standard errno constants from the `errno` module
206
207
### FuseError Exception
208
209
The library provides a specialized exception for FUSE-specific errors:
210
211
```python
212
try:
213
# FUSE operation that might fail
214
result = fuse.feature_assert('has_init')
215
except fuse.FuseError as e:
216
print(f"FUSE error: {e}")
217
```
218
219
### Automatic Error Conversion
220
221
The library automatically converts Python exceptions to appropriate errno values:
222
223
```python
224
def read(self, path, size, offset):
225
try:
226
return self.files[path][offset:offset+size]
227
except KeyError:
228
# Automatically converted to -errno.ENOENT
229
raise OSError(errno.ENOENT, "File not found")
230
except Exception as e:
231
# Generic errors become EIO
232
raise OSError(errno.EIO, str(e))
233
```
234
235
## API Versioning
236
237
fuse-python supports multiple API versions for backward compatibility:
238
239
- **Current API**: `(0, 2)` - Recommended for new code
240
- **Legacy API**: `(0, 1)` - For compatibility with older code
241
242
### Setting API Version
243
244
Set the API version before creating filesystem instances:
245
246
```python
247
fuse.fuse_python_api = (0, 2)
248
```
249
250
Or use environment variable:
251
252
```bash
253
export FUSE_PYTHON_API=0.2
254
```
255
256
### API Version Management Functions
257
258
```python
259
# Check current API version
260
api_version = fuse.get_fuse_python_api()
261
print(f"Using API version: {api_version}")
262
263
# Check if using legacy 0.1 compatibility
264
if fuse.get_compat_0_1():
265
print("Running in 0.1 compatibility mode")
266
267
# Get underlying FUSE library version
268
fuse_version = fuse.APIVersion()
269
print(f"FUSE library version: {fuse_version}")
270
271
# Check feature availability and requirements
272
try:
273
# Check if specific features are available
274
version_needed = fuse.feature_needs('has_init', 'has_destroy')
275
print(f"Features require API version: {version_needed}")
276
277
# Assert that features are available (raises FuseError if not)
278
fuse.feature_assert('has_init', 'has_destroy')
279
print("All required features are available")
280
except fuse.FuseError as e:
281
print(f"Feature check failed: {e}")
282
```
283
284
## Threading
285
286
Filesystems can be multithreaded by setting the `multithreaded` attribute:
287
288
```python
289
class MyFS(Fuse):
290
def __init__(self, *args, **kwargs):
291
super().__init__(*args, **kwargs)
292
self.multithreaded = True
293
```
294
295
Thread safety depends on the filesystem implementation.