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) always return named tuples (Quota,NextQuota,QuotaInfo). Thereturn_typeparameter has been removed; results are tuple-compatible (indexing, unpacking).get_user_quota_namedand other*_namedfunctions are removed; use the correspondingget_*.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.QFMT_VFS_OLD,QFMT_VFS_V0,QFMT_VFS_V1are no longer exported. UseQuotaFormat.VFS_OLD,QuotaFormat.VFS_V0,QuotaFormat.VFS_V1forquota_onand for comparing withget_*_quota_format()return value.DQF_ROOT_SQUASH,DQF_SYS_FILEare no longer exported. UseQuotaInfoFlags.ROOT_SQUASH,QuotaInfoFlags.SYS_FILEforset_*_quota_info(..., flags=...)(combine with|).EACCES,EPERM, and other errno constants are no longer exported. UseQuotaErrno.EACCES,QuotaErrno.EPERM, etc. for comparing withAPIError.errno.
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 return named tuples (Quota, NextQuota, QuotaInfo), which are tuple-compatible (indexing and unpacking work). QuotaInfo has .root_squash and .sys_file properties; use QuotaInfoFlags (IntEnum: ROOT_SQUASH, SYS_FILE) for set_*_quota_info(..., flags=...) (combine with |). iter_user_quotas(device, start_uid=0) (and iter_group_quotas, iter_project_quotas) yield NextQuota for each ID with quota; they use get_next_* under the hood, so get_next_* remains the primitive for a single "next" query. QuotaFormat (IntEnum: VFS_OLD, VFS_V0, VFS_V1) can be used for quota_on / format checks. Errors raised from the public API have .device and .id set when applicable. set_*_quota validates that limits are non-negative ints.
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 (QuotaFormat)
pq.user_quota_on("/dev/sda1", pq.QuotaFormat.VFS_V0, "/aquota.user")
# Turn off user quota
pq.user_quota_off("/dev/sda1")
# Get quota (returns Quota named tuple; tuple-compatible)
quota = pq.get_user_quota("/dev/sda1", 1000)
print(quota.block_hard_limit, quota.block_current)
# Get next user with quota (kernel >= 4.6), or iterate all
next_quota = pq.get_next_user_quota("/dev/sda1", 1000) # next_quota.id is the uid
for nq in pq.iter_user_quotas("/dev/sda1"):
print(nq.id, nq.block_current)
# Set user quota (hard 100MB, soft 90MB, no inode limits)
pq.set_user_quota("/dev/sda1", 1000, 102400, 92160, 0, 0)
# Or take the four limit fields from a Quota (e.g. from get_user_quota)
q = pq.get_user_quota("/dev/sda1", 1000)
pq.set_user_quota("/dev/sda1", 1000, limits_from=q)
# Quotafile info (tuple-like; .root_squash and .sys_file for flags)
info = pq.get_user_quota_info("/dev/sda1")
print(info.block_grace, info.inode_grace)
print(info.root_squash, info.sys_file)
pq.set_user_quota_info("/dev/sda1", 604800, 604800, 0) # 1 week grace, no flags
# Format: compare with QuotaFormat.VFS_OLD, .VFS_V0, .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; compare with QuotaErrno (IntEnum: EACCES, EPERM, ENOENT, etc.). When raised from the public API (get/set/iter, quota_on/off, etc.), device and id are set when applicable. 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)
if e.errno == pq.QuotaErrno.EPERM:
print("Permission denied")
Invalid arguments (e.g. empty device path, negative ID, non-int or negative limits in set_*_quota) raise ValueError or TypeError 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.
Metadata
Release files for PyQuota 0.1.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| pyquota-0.1.3.tar.gz | 19.0 kB | With provenance | Details for pyquota-0.1.3.tar.gz |
Built distributions (wheels)
Total release size: 339.1 kB
Release files / pyquota-0.1.3.tar.gz
| Download URL | pyquota-0.1.3.tar.gz |
|---|---|
| Size | 19.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
334053a8945669f5fcf06db148d504b8f5013b9a7abddd94e8217be2813c7cf5
|
|
BLAKE2b-256 checksum How to use checksums |
3e017f7be898e15e53e21fcff21c97050ef1492a918f5a0de083a44fcb8f4aec
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Mar 7, 2026.
Transparency logRelease files / pyquota-0.1.3-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | pyquota-0.1.3-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 40.3 kB |
| Tags | CPython 3.12 Linux glibc 2.17+ x86-64 Linux glibc 2.5+ x86-64 |
|
SHA-256 checksum How to use checksums |
bca505d3c2a5f00f259d622fc36ce66e9cd37be96010c8623b3deba35bd8ebd9
|
|
BLAKE2b-256 checksum How to use checksums |
fa10bc38a70306ed3cae5acde2fa42d17e68faea975f7686efde4e9a06ab3719
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Mar 7, 2026.
Transparency logRelease files / pyquota-0.1.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
| Download URL | pyquota-0.1.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl |
|---|---|
| Size | 37.1 kB |
| Tags | CPython 3.12 Linux glibc 2.17+ x86-32 Linux glibc 2.5+ x86-32 |
|
SHA-256 checksum How to use checksums |
00a6dae9ae8c9961f252a1c4b906db65dc4ebe5a9b5e2f2147fc6d650a50553f
|
|
BLAKE2b-256 checksum How to use checksums |
3021d2acf946a6fed3d48a736471beb42b03493e6d4fe4cbefdb3a2ba3cf7c54
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Mar 7, 2026.
Transparency logRelease files / pyquota-0.1.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | pyquota-0.1.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 42.0 kB |
| Tags | CPython 3.11 Linux glibc 2.17+ x86-64 Linux glibc 2.5+ x86-64 |
|
SHA-256 checksum How to use checksums |
5e02eb1af0c9bfcd54b054f54848b471670cebb2ade6ca8315265f1e4532e819
|
|
BLAKE2b-256 checksum How to use checksums |
dd96d906e23a5ed59139e8ced2714006f82c070f9114b4dd92d51e886cb1ea38
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Mar 7, 2026.
Transparency logRelease files / pyquota-0.1.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
| Download URL | pyquota-0.1.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl |
|---|---|
| Size | 39.2 kB |
| Tags | CPython 3.11 Linux glibc 2.17+ x86-32 Linux glibc 2.5+ x86-32 |
|
SHA-256 checksum How to use checksums |
01ed6f77a31de308046e9e0963ef7f379282dc5252735a586401339dbc3eccbd
|
|
BLAKE2b-256 checksum How to use checksums |
809efc932619bb23aa1f08f55281fab56f7cbaade75200256af9411b7350a7c4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Mar 7, 2026.
Transparency logRelease files / pyquota-0.1.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | pyquota-0.1.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 42.0 kB |
| Tags | CPython 3.10 Linux glibc 2.17+ x86-64 Linux glibc 2.5+ x86-64 |
|
SHA-256 checksum How to use checksums |
3775d416c9911bb9881d60168631c2d51a5ad5198a0da0ca320711ebcd82a1ac
|
|
BLAKE2b-256 checksum How to use checksums |
47771f6508c4eef0ce47e7cb8ae7936fbf426f2843f198892c62f474d7072f19
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Mar 7, 2026.
Transparency logRelease files / pyquota-0.1.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
| Download URL | pyquota-0.1.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl |
|---|---|
| Size | 39.2 kB |
| Tags | CPython 3.10 Linux glibc 2.17+ x86-32 Linux glibc 2.5+ x86-32 |
|
SHA-256 checksum How to use checksums |
767bcdd669ed9a3c9526b86ba2e39d7b2921ad398192571ca6f3d7038ae884b2
|
|
BLAKE2b-256 checksum How to use checksums |
10fd0d96a19f35848d73c118eaf30e3666ad39a8d40445cbfe6a2f4ca5617b50
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Mar 7, 2026.
Transparency logRelease files / pyquota-0.1.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | pyquota-0.1.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 41.6 kB |
| Tags | CPython 3.9 Linux glibc 2.17+ x86-64 Linux glibc 2.5+ x86-64 |
|
SHA-256 checksum How to use checksums |
5148bd51aa8fe549ca6f587cda82a87a10bfc614c3fb029da8ad5fd39a73f868
|
|
BLAKE2b-256 checksum How to use checksums |
2c547e0a056d9a1a86fd816d1baa911964da6cd8bdc3cf379fa0a96b358fcdcc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Mar 7, 2026.
Transparency logRelease files / pyquota-0.1.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
| Download URL | pyquota-0.1.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl |
|---|---|
| Size | 38.9 kB |
| Tags | CPython 3.9 Linux glibc 2.17+ x86-32 Linux glibc 2.5+ x86-32 |
|
SHA-256 checksum How to use checksums |
4710478a138c7b776e2b755ad42f598cb116f4b3699b8610bdf10979a62cdbbf
|
|
BLAKE2b-256 checksum How to use checksums |
c7eb2b675273cc8b59b2fdb05dd6f57bcc3853ff2984b69dc9869a3d95818e4b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Mar 7, 2026.
Transparency logSecurity for PyQuota 0.1.3
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 9 files in this release have been uploaded with provenance metadata.
Attestation for pyquota-0.1.3.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Mar 7, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.