A Python wrapper for Linux quotactl(2) APIs
Project description
PyQuota
PyQuota is a Python wrapper for the Linux quotactl(2) APIs.
Requirements
- Linux with quota support (kernel built with
CONFIG_QUOTA) - Privilege: root or
CAP_SYS_ADMINfor quota operations - Kernel: >= 2.4.22; project quota requires >= 4.1;
Q_GETNEXTQUOTArequires >= 4.6
XFS-specific quotactl commands (e.g. Q_XQUOTAON) are not supported.
Future work: Linux 5.13+ adds quotactl_fd(), which uses a file descriptor instead of a device path (useful for filesystems without a block device, e.g. UBIFS). This wrapper does not yet support it.
Breaking changes (current release)
get_user_quota,get_next_user_quota,get_user_quota_info(and group/project) now take an optionalreturn_typeand default to named tuples. Usereturn_type="tuple"to get the raw tuple (e.g.pq.get_user_quota(device, uid, return_type="tuple")).get_user_quota_namedand other*_namedfunctions are removed; use the correspondingget_*with defaultreturn_type="named".get_user_quota_with_validand other*_with_validfunctions are replaced byget_*_quota_partial(andget_*_quota_info_partial), which return named tuples only (QuotaPartial,NextQuotaPartial,QuotaInfoPartial) with optional fields asNonewhen not set.
Installation
pip install pyquota
From source (build deps: Python development headers, C compiler):
git clone https://github.com/tjumyk/pyquota.git && cd pyquota
pip install -e .
Units
- Block limits (
block_hard_limit,block_soft_limit): in 1024-byte disk quota blocks (quotactl(2)) - Current block usage (
block_current): in bytes - Inode limits/current: inodes (count)
- Grace periods (
block_grace,inode_graceinQuotaInfo): in seconds before soft limit becomes hard - Time limits (
block_time,inode_timeinQuota): Unix timestamps (seconds since epoch) when grace expires, or 0 if not over soft limit
API overview
| quotactl command | User quota | Group quota | Project quota |
|---|---|---|---|
| Q_QUOTAON | user_quota_on |
group_quota_on |
project_quota_on |
| Q_QUOTAOFF | user_quota_off |
group_quota_off |
project_quota_off |
| Q_GETQUOTA | get_user_quota |
get_group_quota |
get_project_quota |
| Q_GETNEXTQUOTA | get_next_user_quota |
get_next_group_quota |
get_next_project_quota |
| Q_SETQUOTA | set_user_quota |
set_group_quota |
set_project_quota |
| Q_GETINFO | get_user_quota_info |
get_group_quota_info |
get_project_quota_info |
| Q_SETINFO | set_user_quota_info |
set_group_quota_info |
set_project_quota_info |
| Q_GETFMT | get_user_quota_format |
get_group_quota_format |
get_project_quota_format |
| Q_SYNC | sync_user_quotas |
sync_group_quotas |
sync_project_quotas |
Return type: get_*_quota, get_next_*_quota, and get_*_quota_info accept an optional return_type ("named" | "tuple"). Default is "named", returning Quota, NextQuota, or QuotaInfo. Use return_type="tuple" for the raw tuple.
Partial validity: When the kernel may return incomplete data, use get_*_quota_partial or get_*_quota_info_partial. They return named tuples (QuotaPartial, etc.) where fields the kernel did not set are None (interpreted from the kernel’s valid mask per man 2 quotactl). Use e.g. if q.block_hard_limit is not None:. According to the man page, the kernel currently always fills all fields and sets the valid mask to QIF_ALL/IIF_ALL on get; the valid mask is used on set to indicate which fields the caller provides. The partial API exists for forward compatibility if a kernel ever returns incomplete data.
Usage
import pyquota as pq
# Turn on user quota for a filesystem
pq.user_quota_on("/dev/sda1", pq.QFMT_VFS_V0, "/aquota.user")
# Turn off user quota
pq.user_quota_off("/dev/sda1")
# Get quota (default: named tuple Quota)
quota = pq.get_user_quota("/dev/sda1", 1000)
print(quota.block_hard_limit, quota.block_current)
# Raw tuple: use return_type="tuple"
raw = pq.get_user_quota("/dev/sda1", 1000, return_type="tuple")
# Get next user with quota (kernel >= 4.6)
next_quota = pq.get_next_user_quota("/dev/sda1", 1000) # next_quota.id is the uid
# Set user quota (hard 100MB, soft 90MB, no inode limits)
pq.set_user_quota("/dev/sda1", 1000, 102400, 92160, 0, 0)
# Or pass the result of get_user_quota (only the four limit fields are applied)
q = pq.get_user_quota("/dev/sda1", 1000)
pq.set_user_quota("/dev/sda1", 1000, quota=q)
# Quotafile info (grace periods in seconds, flags)
info = pq.get_user_quota_info("/dev/sda1")
print(info.block_grace, info.inode_grace)
print(bool(info.flags & pq.DQF_ROOT_SQUASH), bool(info.flags & pq.DQF_SYS_FILE))
pq.set_user_quota_info("/dev/sda1", 604800, 604800, 0) # 1 week grace, no flags
# Format: QFMT_VFS_OLD, QFMT_VFS_V0, or QFMT_VFS_V1
fmt = pq.get_user_quota_format("/dev/sda1")
# Sync quota usage to disk
pq.sync_user_quotas("/dev/sda1")
pq.sync_user_quotas(None) # all filesystems with active user quotas
Replace user with group or project for group/project quotas. Project quota requires kernel >= 4.1.
Error handling
Errors from the C API are raised as pyquota.APIError (or a subclass) with messages matching the quotactl(2) ERRORS section. Each instance has an errno attribute. Subclasses: PermissionError (EPERM), NotFoundError (ENOENT, ESRCH), InvalidError (EINVAL, etc.); catch pq.APIError or use e.errno.
import pyquota as pq
try:
pq.get_user_quota("/dev/sda1", 1000)
except pq.PermissionError:
print("Need root or CAP_SYS_ADMIN")
except pq.NotFoundError as e:
print("Not found:", e)
except pq.APIError as e:
print(e, "errno:", e.errno)
Invalid arguments (e.g. empty device path, negative ID) raise ValueError before calling the kernel.
Reference
See the man page for detailed semantics of each command. Type stubs (.pyi) are provided for IDE completion and type checkers. API documentation is built with Sphinx and published at https://tjumyk.github.io/pyquota/ when available.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pyquota-0.1.2.tar.gz.
File metadata
- Download URL: pyquota-0.1.2.tar.gz
- Upload date:
- Size: 16.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.25
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
494fb58db048cf5463f2c0205538ac8917a268eabb25d7018d5874521d5f95b8
|
|
| MD5 |
a592e0f6293628a6d2a8ba3726fc4a2a
|
|
| BLAKE2b-256 |
bd1cfdb288efff3c64ddcc22efcd2db3bf76fbf19c780de5b5b66b23860a78b5
|
File details
Details for the file pyquota-0.1.2-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: pyquota-0.1.2-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 37.9 kB
- Tags: CPython 3.13, manylinux: glibc 2.17+ x86-64, manylinux: glibc 2.5+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.25
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
58f5353aba31d5d6dbcd9b297b991e9b31fbcb8df6f547fa6f129026fbc26331
|
|
| MD5 |
df951a17b52938c3d0eabbd0b336e199
|
|
| BLAKE2b-256 |
b86ef7a0fcf8f6debc1d9a62644d9e6b35a019283167c3d41df40ee94612f2c7
|
File details
Details for the file pyquota-0.1.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl.
File metadata
- Download URL: pyquota-0.1.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
- Upload date:
- Size: 34.7 kB
- Tags: CPython 3.13, manylinux: glibc 2.17+ i686, manylinux: glibc 2.5+ i686
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.25
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1873367f9529c744c047e008bbfbb2e47d5505d05d74fd9d59ff371f19957634
|
|
| MD5 |
122eaaac509179e96709dea0dd29c007
|
|
| BLAKE2b-256 |
d8b7946f0de6c183d52ae2476f53cecad898d48b05b064892d7947fa2c67c26b
|
File details
Details for the file pyquota-0.1.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: pyquota-0.1.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 37.9 kB
- Tags: CPython 3.12, manylinux: glibc 2.17+ x86-64, manylinux: glibc 2.5+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.25
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0b8680fd69e12ce23cae2a85d135ee933cf1979026a4736f70b9d8e0e4f7f801
|
|
| MD5 |
422aedc536854a298838679b1573d618
|
|
| BLAKE2b-256 |
46574b97d7b442943ec4a9781cc4949c142f3a30410b74cded3fa4dc163f6d05
|
File details
Details for the file pyquota-0.1.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl.
File metadata
- Download URL: pyquota-0.1.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
- Upload date:
- Size: 34.8 kB
- Tags: CPython 3.12, manylinux: glibc 2.17+ i686, manylinux: glibc 2.5+ i686
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.25
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fafb2e6d29d9bd0d0ec37629e222f9cb1587bf41384268a33f503fe97c8d708e
|
|
| MD5 |
e21def2448f26b9abaf636b83e4edc3f
|
|
| BLAKE2b-256 |
46630a5ec5930c8534c3ed2259387143d834b8e71fb235d017ac252ac1fff02f
|
File details
Details for the file pyquota-0.1.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: pyquota-0.1.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 39.6 kB
- Tags: CPython 3.11, manylinux: glibc 2.17+ x86-64, manylinux: glibc 2.5+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.25
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
17f8fc57c3732625e78a55ec1e12bf2b37845380b3a0dd8f25635b8820c181bf
|
|
| MD5 |
ef14c434ce8549b03cc4dd64b373ae3e
|
|
| BLAKE2b-256 |
6a44420198fed260cca141fb438bd79d846eb82d907bf47a09a2bb0f54e9e9dc
|
File details
Details for the file pyquota-0.1.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl.
File metadata
- Download URL: pyquota-0.1.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
- Upload date:
- Size: 36.8 kB
- Tags: CPython 3.11, manylinux: glibc 2.17+ i686, manylinux: glibc 2.5+ i686
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.25
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
50808a18b4de72528299054612b89d11093b5776ca33c45cb6b853bab5f45c27
|
|
| MD5 |
f814c9b6efab91a9bd8b98c123804cd6
|
|
| BLAKE2b-256 |
c6a75aca289d83ad7627e2332ae97f0a5079feacfd54b247971307da52da21f5
|
File details
Details for the file pyquota-0.1.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: pyquota-0.1.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 39.6 kB
- Tags: CPython 3.10, manylinux: glibc 2.17+ x86-64, manylinux: glibc 2.5+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.25
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
711a194202b336eca90db492a251498813c98240f5cb66f6bd4c057b3605d5ff
|
|
| MD5 |
15a68c6ec21c4cadbb5a22224542fc6b
|
|
| BLAKE2b-256 |
5c8d3200d83db7421e21a3becaba5b50e9f67f1bf9a09ba3de7ba111721f12b9
|
File details
Details for the file pyquota-0.1.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl.
File metadata
- Download URL: pyquota-0.1.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
- Upload date:
- Size: 36.9 kB
- Tags: CPython 3.10, manylinux: glibc 2.17+ i686, manylinux: glibc 2.5+ i686
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.25
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fedc30530cfc959e82d5a778db77b70ed001e29657719900ec6406af267280a2
|
|
| MD5 |
3068632a54ef65db2a2a3f1524d3acb9
|
|
| BLAKE2b-256 |
67a89d42b0c385d0956b7242f7395e6a99d41fb304c5050ec977393d2ee2f9b5
|
File details
Details for the file pyquota-0.1.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: pyquota-0.1.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 39.2 kB
- Tags: CPython 3.9, manylinux: glibc 2.17+ x86-64, manylinux: glibc 2.5+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.25
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0ada053a6636739cb7ba758676d44b8d7ee3813d5c7aeaacbb4808b5cc1bfbf9
|
|
| MD5 |
4bf41f27aca399be064ff1cdbc7d5f0f
|
|
| BLAKE2b-256 |
1cfac43087825aaba905d405740e2751854768ea3bd548c6bf1b83c8d739e449
|
File details
Details for the file pyquota-0.1.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl.
File metadata
- Download URL: pyquota-0.1.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
- Upload date:
- Size: 36.5 kB
- Tags: CPython 3.9, manylinux: glibc 2.17+ i686, manylinux: glibc 2.5+ i686
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.25
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2858abf50f7d731142c7b882bad6fdec841c22c7d5ac760d5b15f64e5d6dbdce
|
|
| MD5 |
579cb56f39f1a9796bcac236565afcd5
|
|
| BLAKE2b-256 |
184ff54153db06a8ed39d2308cf554b85c04552e66c9b8742057036c24c92d8c
|