Aird - A lightweight web-based file browser, editor, and streamer with real-time capabilities
Project description
Aird
Aird is a self-hosted file browser, editor, and sharing platform built on Python and Tornado. It targets fast local and LAN use: parallel HTTP transfers for large files, real-time log streaming, content search, secure shares, optional multi-user isolation, and an admin console that applies settings without restarts.
Highlights
| Area | What you get |
|---|---|
| File manager | Browse, upload, download, rename, move, copy, bulk ops, in-browser text edit, ZIP download |
| Large transfers | Parallel HTTP Content-Range uploads/downloads (primary path for big files) |
| Search | Super Search — glob + regex content search with live WebSocket progress |
| Streaming | Tail log files over WebSocket with filters |
| Sharing | Token-based public/private shares, static or live folder views |
| Security | CSRF, CSP, path traversal checks, optional ABAC policies, WebAuthn, LDAP |
| Integrations | Google Drive / OneDrive browse, P2P WebRTC rooms, optional embedded SMB & WebDAV |
| Ops | SQLite-backed settings, audit log, feature flags, transfer rate limits, health endpoint |
File transfers
Large uploads are designed for high-throughput links (e.g. gigabit LAN or VPN):
- Small files — single
POST /upload. - Large files — client opens a range session (
POST /api/upload/range/session), then sends many parallelPUTrequests withContent-Range. Each chunk is written in place at the correct byte offset on disk (no separate part files, no concat step at the end). - Downloads —
GET /files/...?download=1with optionalRangefor parallel fetch.
Defaults (all adjustable in Admin → Upload settings):
| Setting | Default | Notes |
|---|---|---|
| Max file size | 10 240 MB (10 GiB) | Hard cap per file |
| Single-request max | 100 MB | Files ≥ this use parallel HTTP ranges |
| HTTP chunk size | 90 MB | Per range PUT body |
| HTTP parallelism | 16 | Concurrent upload streams |
Behind nginx/Caddy: set client_max_body_size (or equivalent) to at least your HTTP chunk size. If Single-request max is 0, Aird uses a 100 MB parallel threshold (proxy-safe), not a single POST for the entire max file size.
Optional WebSocket upload (/ws/file-transfer) remains for specialized paths; the browser UI uses HTTP parallel by default.
Transfer progress, cancel, and resume metadata are handled in the browser (transfer-tracker.js, transfer-engine/, service worker sw-transfer.js).
Quick start
Install
pip install aird
# Optional: HTTP response compression codecs (gzip is always available)
pip install "aird[compress]"
# From source
git clone https://github.com/blinkerbit/aird.git
cd aird
pip install -e .
Python: 3.10+ required. On Linux, free-threaded builds (3.13t / 3.14t) are supported and recommended for parallel disk I/O; the server detects nogil at startup and sizes the I/O thread pool accordingly.
Run
# Default: port 8000, current directory as root
python -m aird
# Custom root and port
python -m aird --root /data --port 8080
# Multi-user (per-user home directories under root)
python -m aird --root /data --multi-user
# TLS
python -m aird --ssl-cert /path/cert.pem --ssl-key /path/key.pem --port 443
# Worker processes (Linux; default is auto from CPU topology)
python -m aird --workers 4
On first start, random access and admin tokens are printed unless you set them via --token, --admin-token, config.json, or AIRD_ACCESS_TOKEN.
Open http://localhost:8000/ → redirects to /files/.
CLI client
pip install aird # includes aird-cli
aird-cli config set server https://your-host
aird-cli login
aird-cli ls /
Configuration
config.json
{
"port": 8000,
"root": "/srv/files",
"hostname": "files.example.com",
"token": "your-access-token",
"admin_token": "your-admin-token",
"multi_user": false,
"workers": 2,
"ldap": {
"enabled": false,
"server": "ldap://ldap.example.com",
"base_dn": "dc=example,dc=com"
},
"feature_flags": {
"file_upload": true,
"super_search": true,
"abac_engine": false
}
}
python -m aird --config /etc/aird/config.json
Environment variables (common)
| Variable | Purpose |
|---|---|
AIRD_ACCESS_TOKEN |
Login token |
AIRD_COOKIE_SECRET |
Persistent session signing (set in production) |
AIRD_CORPORATE_IP_CIDRS |
Comma-separated CIDRs for ABAC / WAN compression rules |
AIRD_GDRIVE_ACCESS_TOKEN / AIRD_ONEDRIVE_ACCESS_TOKEN |
Cloud providers |
Admin console
GET /admin — feature flags, upload limits, extension allow-list, WebSocket pool limits, LDAP, network shares, ABAC policies/tags, users, audit. Changes persist to SQLite and apply without restart (feature-flag subscribers refresh over /features WebSocket).
Production deployment
Reverse proxy
Aird listens on one port (default 8000). Terminate TLS at Caddy, nginx, or similar.
nginx example (adjust chunk size to match Admin → HTTP chunk):
client_max_body_size 128m;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
WebSocket routes (/stream/, /search/ws, /features, /ws/…) need Upgrade and Connection headers if you proxy them.
Ubuntu deploy script
deploy_local.ps1 (run from Windows) syncs source or a wheel to a remote host, creates a uv venv with Python 3.14t, and installs the package. See docs/wireguard-deploy.md for VPN-only TLS layouts.
Systemd
Run python -m aird (or the venv equivalent) as a service user with --config pointing at your JSON file. Logs go to the data directory (aird.log under the platform app data path).
API overview
Authentication: session cookie after /login, bearer token, or Authorization header where supported. Mutating requests require the _xsrf cookie + X-XSRFToken header.
| Operation | Method / path |
|---|---|
| List directory | GET /api/files/{path} |
| Upload (small) | POST /upload |
| Upload (large) | POST /api/upload/range/session then PUT /api/upload/range/{id} |
| Upload status | GET /api/upload/range/{id}/status |
| Download | GET /files/{path}?download=1 |
| Edit | GET /edit/{path}, POST /edit |
| Delete / rename / mkdir | POST /delete, POST /rename, POST /mkdir |
| Search UI | GET /search |
| Search (live) | WebSocket /search/ws |
| Log stream | WebSocket /stream/{path} |
| Shares | POST /share/create, GET /share/list, … |
| Health | GET /health |
Page-level UI contracts and routes are documented under docs/.
Architecture notes
- Async I/O: Tornado event loop; on Linux optionally uvloop.
- Free-threaded Python: SQLite access is wrapped (
aird/db/sync.py); upload chunk writes useasyncio.to_thread/os.pwriteso parallel range PUTs do not block the loop. - HTTP compression:
gzipby default; optionalzstandardviapip install aird[compress](loaded only on builds where the extension is nogil-safe). - Security headers: COOP/COEP/CORP for transfer workers; strict CSP on HTML pages.
- ABAC: Optional policy engine (
abac_engineflag) with admin-defined policies, tags, and user attributes.
Development
Frontend assets
npm install
npm run css:build # Tailwind → aird/static/css/app.css
npm run js:share # Bundle share UI
npm run vendor:fflate # Compression worker dependency
Tests
python -m pytest tests/
Project layout
aird/
handlers/ # HTTP & WebSocket handlers
services/ # Config, quota, share, audit, …
static/js/ # Browser UI & transfer engine
templates/ # Jinja2 pages
core/ # Compression, mmap, rate limits, …
docs/ # Per-page UI & admin documentation
Security
- Path traversal and symlink checks on file access
- Argon2 password hashing for local users
- CSRF on state-changing requests
- Upload extension allow-list (or allow-all) with max size enforced server-side
- Optional storage quotas (multi-user)
- Audit trail and live policy-decision stream for ABAC
Report issues via GitHub. For production, set AIRD_COOKIE_SECRET, use TLS, and restrict admin routes.
License
Business Source License 1.1 (BSL) — see LICENSE. Converts to Apache 2.0 after the change date in the license file.
Commercial File-Management-as-a-Service use requires a separate license. Contact Viswanatha Srinivas P.
Links
- Repository: https://github.com/blinkerbit/aird
- PyPI: https://pypi.org/project/aird/
- UI / admin docs: docs/README.md · docs/transfers.md
- Issues: https://github.com/blinkerbit/aird/issues
Made by Viswanatha Srinivas P
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
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 aird-0.4.25.dev3.tar.gz.
File metadata
- Download URL: aird-0.4.25.dev3.tar.gz
- Upload date:
- Size: 2.0 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cda899ba3ea68d98c6f0f481048c4ca830b6a8b3318a1a02080e6dc02d888389
|
|
| MD5 |
28740ba68acb694fd83084a07c1670bb
|
|
| BLAKE2b-256 |
13976395e366ca739103bf40f2e2a31b99ca848abc59a67f24cfcec613ff7b48
|
File details
Details for the file aird-0.4.25.dev3-py3-none-any.whl.
File metadata
- Download URL: aird-0.4.25.dev3-py3-none-any.whl
- Upload date:
- Size: 2.2 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
954bcf3c543b0b60f83beb38c19327f3162c62bdb6c42a7f9b1062c1471689da
|
|
| MD5 |
c476d4727cc5cd5ecf78bf225b542ae0
|
|
| BLAKE2b-256 |
9a939cfa8b22a7a4ea6ac90efd7a8aa4bd55df94bcc4c97e762fe524c1391f01
|