Reviewed-on: #22
pyTorrent
Modern single-page web UI for managing rTorrent through SCGI/XML-RPC. pyTorrent focuses on fast live updates, multi-profile support, automation, diagnostics and a clean browser-based workflow inspired by ruTorrent.
pyTorrent is a controller for your own rTorrent instance. It does not include a BitTorrent engine and does not bypass tracker, copyright or network rules.
Highlights
- Live torrent table with WebSocket updates and patch-based refreshes.
- Multiple rTorrent profiles, including local and remote hosts.
- Profile-level permissions, user management and API tokens.
- Bulk torrent actions: start, pause, stop, resume, recheck, remove and move.
- Background move/remove jobs with operation history.
- Smart Queue with recent job status and expandable history.
- Download Planner with quiet hours, speed limits, CPU/disk protection and dry-run mode.
- Adaptive Poller with configurable intervals and diagnostics.
- RSS tools, automation rules and cleanup helpers.
- Torrent details: general data, files, peers, trackers and logs.
- Peer GeoIP lookup with MaxMind GeoLite2 database support.
- Dashboard, smart views, global search and notification center.
- OpenAPI docs available from the app.
- Offline frontend assets support for self-hosted deployments.
Screenshots
Requirements
Application
- Python 3.10+
- rTorrent with SCGI/XML-RPC enabled
- Linux server recommended for production
Python packages
The project uses Flask, Flask-SocketIO, python-dotenv, psutil, geoip2, gunicorn and related runtime dependencies listed in requirements.txt.
Quick start
Clone the repository and run the local installer:
git clone https://github.com/zdzichu6969/pyTorrent.git
cd pyTorrent
./install.sh
. venv/bin/activate
python app.py
Default URL:
http://127.0.0.1:8090
Copy the example environment file before customizing the app:
cp .env.example .env
rTorrent SCGI profile
Example pyTorrent profile URL:
scgi://127.0.0.1:5000/RPC2
Example rTorrent configuration:
network.scgi.open_port = 127.0.0.1:5000
For production, keep SCGI bound to localhost or a private trusted network only.
Stack installer
The repository includes a stack installer for a clean server. It can install and configure rTorrent + pyTorrent together.
Supported systems:
- Debian / Ubuntu
- RHEL-compatible distributions: RHEL, Rocky Linux, AlmaLinux, CentOS Stream, Fedora-like systems with
dnforyum - Arch Linux
After cloning the repository:
bash scripts/install_stack.sh
The default stack install creates:
| Component | Default |
|---|---|
| rTorrent user | rtorrent |
| rTorrent SCGI | scgi://127.0.0.1:5000 |
| BitTorrent port | 51300 |
| pyTorrent app dir | /opt/pytorrent |
| pyTorrent HTTP port | 8090 |
| pyTorrent service | pytorrent |
One-line install with rtorrent
curl -fsSL https://raw.githubusercontent.com/zdzichu6969/pyTorrent/main/scripts/install_stack.sh \
| PYTORRENT_PORT=8091 \
RTORRENT_SCGI_PORT=5001 \
PYTORRENT_PROFILE_NAME="Local rTorrent" \
bash
Installer variables
Bootstrap
| Variable | Default | Description |
|---|---|---|
PYTORRENT_REPO_URL |
repository URL | Repository base URL. |
PYTORRENT_REPO_BRANCH |
master |
Branch used by the bootstrap installer. |
PYTORRENT_ARCHIVE_URL |
derived | Custom repository archive URL. Required for GitHub one-line install unless the script default is updated. |
PYTORRENT_BOOTSTRAP_DIR |
/tmp/pytorrent-stack-installer |
Temporary bootstrap directory. |
PYTORRENT_KEEP_BOOTSTRAP_DIR |
0 |
Set to 1 to keep bootstrap files after install. |
rTorrent
| Variable | Default | Description |
|---|---|---|
RTORRENT_USER |
rtorrent |
System user used to run rTorrent. |
RTORRENT_HOME |
/home/${RTORRENT_USER} |
Home directory for the rTorrent user. |
RTORRENT_BASE_DIR |
/opt/rtorrent_build |
Build/install directory for source installs. |
RTORRENT_SCGI_PORT |
5000 |
Local SCGI port. |
RTORRENT_TORRENT_PORT |
51300 |
Incoming BitTorrent port. |
RTORRENT_REF |
v0.16.11 |
rTorrent Git tag, branch or commit for source builds. |
LIBTORRENT_REF |
v0.16.11 |
libtorrent Git tag, branch or commit for source builds. |
RTORRENT_WITH_XMLRPC_C |
0 |
Set to 1 to build with classic xmlrpc-c. |
RTORRENT_BUILD_FROM_SOURCE |
distro-specific | On Arch, set to 1 to compile instead of using pacman. |
RTORRENT_FORCE_CONFIG |
1 |
Overwrite generated .rtorrent.rc when supported. |
pyTorrent
| Variable | Default | Description |
|---|---|---|
PYTORRENT_APP_DIR |
/opt/pytorrent |
Installation directory. |
PYTORRENT_PORT |
8090 |
HTTP port. |
PYTORRENT_BASE_URL |
http://127.0.0.1:${PYTORRENT_PORT} |
Base URL used by the API configurator. |
PYTORRENT_PROFILE_NAME |
Local rTorrent |
rTorrent profile created in pyTorrent. |
PYTORRENT_API_TOKEN |
empty | Bearer token for authenticated API calls during setup. |
PYTORRENT_SERVICE_NAME |
pytorrent |
systemd service name. |
PYTORRENT_RTORRENT_SCGI_URL |
scgi://127.0.0.1:${RTORRENT_SCGI_PORT} |
SCGI URL saved in the generated profile. |
Production run
Recommended production command:
. venv/bin/activate
gunicorn --worker-class gthread \
--workers 1 \
--threads 32 \
--bind 0.0.0.0:8090 \
--access-logfile - \
--error-logfile - \
wsgi:app
pyTorrent uses Flask-SocketIO with threading mode. Multiple Gunicorn workers are not a drop-in replacement unless a Socket.IO message queue such as Redis, RabbitMQ or Kafka is configured.
systemd
Useful service commands after stack installation:
systemctl status pytorrent
systemctl status rtorrent@rtorrent.service
journalctl -u pytorrent -f
journalctl -u rtorrent@rtorrent.service -f
Application logs may also be available in:
data/logs/
Reverse proxy
Enable proxy header handling only when pyTorrent is behind a trusted proxy:
PYTORRENT_PROXY_FIX_ENABLE=true
PYTORRENT_SESSION_COOKIE_SECURE=true
Forward these headers from the proxy:
X-Forwarded-For
X-Forwarded-Proto
X-Forwarded-Host
X-Forwarded-Port
If pyTorrent is mounted under a sub-path, also forward:
X-Forwarded-Prefix
For HTTPS deployments, set allowed origins explicitly:
PYTORRENT_SOCKETIO_CORS_ALLOWED_ORIGINS=https://pytorrent.example.com
PYTORRENT_API_ALLOWED_ORIGINS=https://pytorrent.example.com
Authentication
pyTorrent supports three authentication providers:
| Provider | Description |
|---|---|
local |
Built-in pyTorrent login screen with username and password. |
tinyauth |
External authentication through Tinyauth and a trusted reverse proxy header. |
proxy |
Generic external authentication through a trusted reverse proxy header. |
Enable authentication:
PYTORRENT_AUTH_ENABLE=true
PYTORRENT_AUTH_PROVIDER=local
Reset a local user's password:
. venv/bin/activate
python -m pytorrent.cli reset-password admin new_password
Without the password argument, the command asks interactively:
python -m pytorrent.cli reset-password admin
API tokens
When authentication is enabled, API requests can use a browser session cookie or a per-user API token. Admin users can generate tokens in:
Tools -> Users -> Generate token
Use the token as a bearer token or API key:
curl -H "Authorization: Bearer pt_xxx" http://127.0.0.1:8090/api/system/status
curl -H "X-API-Key: pt_xxx" http://127.0.0.1:8090/api/system/status
Token permissions follow the owning user's role and profile permissions. Revoked tokens stop working immediately.
External auth through Tinyauth or proxy
Example Tinyauth configuration:
PYTORRENT_AUTH_ENABLE=true
PYTORRENT_AUTH_PROVIDER=tinyauth
PYTORRENT_AUTH_PROXY_USER_HEADER=Remote-User
PYTORRENT_AUTH_PROXY_AUTO_CREATE=true
PYTORRENT_AUTH_PROXY_AUTO_CREATE_ROLE=admin
PYTORRENT_AUTH_PROXY_AUTO_CREATE_PERMISSION=rw
Example generic proxy configuration:
PYTORRENT_AUTH_ENABLE=true
PYTORRENT_AUTH_PROVIDER=proxy
PYTORRENT_AUTH_PROXY_USER_HEADER=X-Forwarded-User
PYTORRENT_AUTH_PROXY_AUTO_CREATE=true
PYTORRENT_AUTH_PROXY_AUTO_CREATE_ROLE=user
PYTORRENT_AUTH_PROXY_AUTO_CREATE_PERMISSION=rw
rw is accepted as an alias for full. Admin users can access all profiles.
Do not use auth bypass on public hostnames. Limit bypass hosts to trusted private addresses only:
PYTORRENT_AUTH_BYPASS_HOSTS=10.11.1.11:8090,10.11.1.11
PYTORRENT_AUTH_BYPASS_USER=admin
GeoIP
The installer can download the GeoLite2 City database to:
data/GeoLite2-City.mmdb
Manual download:
./scripts/download_geoip.sh
Configure the database path:
PYTORRENT_GEOIP_DB=data/GeoLite2-City.mmdb
OpenAPI
OpenAPI documentation is available at:
/docs
/api/openapi.json
The API includes profile management, torrent actions, preferences, port checks, system status, planner, poller, RSS, backups and diagnostics endpoints.
Configuration reference
Common environment variables:
PYTORRENT_SECRET_KEY=change-me
PYTORRENT_DB_PATH=data/pytorrent.sqlite3
PYTORRENT_HOST=0.0.0.0
PYTORRENT_PORT=8090
PYTORRENT_DEBUG=0
PYTORRENT_POLL_INTERVAL=1
PYTORRENT_WORKERS=16
PYTORRENT_USE_OFFLINE_LIBS=true
PYTORRENT_LOG_ENABLE=false
PYTORRENT_LOG_DIR=data/logs
Retention settings:
PYTORRENT_TRAFFIC_HISTORY_RETENTION_DAYS=90
PYTORRENT_JOBS_RETENTION_DAYS=30
PYTORRENT_SMART_QUEUE_HISTORY_RETENTION_DAYS=30
PYTORRENT_LOG_RETENTION_DAYS=30
Database maintenance:
PYTORRENT_DB_VACUUM_ENABLE=true
PYTORRENT_DB_VACUUM_EVERY_SECONDS=86400
PYTORRENT_DB_VACUUM_MIN_FREE_MB=512
PYTORRENT_DB_VACUUM_MIN_FREE_RATIO=0.25
See .env.example for the full list.
Troubleshooting
Service does not start
journalctl -u pytorrent -n 100 --no-pager
systemctl status pytorrent
rTorrent connection fails
Check that rTorrent exposes SCGI locally and that the pyTorrent profile uses the same port:
scgi://127.0.0.1:5000/RPC2
External auth creates users without profiles
Use admin auto-create mode:
PYTORRENT_AUTH_PROXY_AUTO_CREATE_ROLE=admin
Or grant read-write profile permissions to non-admin users:
PYTORRENT_AUTH_PROXY_AUTO_CREATE_ROLE=user
PYTORRENT_AUTH_PROXY_AUTO_CREATE_PERMISSION=rw
Socket.IO badge stays offline behind reverse proxy
Forward the same authenticated user header to all pyTorrent paths, including /socket.io/:
auth_request_set $auth_user $upstream_http_remote_user;
proxy_set_header Remote-User $auth_user;
Build logs
Source-build installers write logs to:
/var/log/pytorrent-installer
Enable verbose installer output:
PYTORRENT_DEBUG_INSTALL=1 bash scripts/install_stack.sh
Security notes
- Do not expose rTorrent SCGI directly to the public internet.
- Use HTTPS and authentication for remote access.
- Set a strong
PYTORRENT_SECRET_KEYbefore production use. - Review auth bypass settings before publishing or deploying.
- Keep
.envout of Git. Use.env.examplefor public defaults.
Development
. venv/bin/activate
python app.py
Run a quick Python compile check:
python -m compileall pytorrent app.py wsgi.py
Download offline frontend assets when needed:
python scripts/download_frontend_libs.py
Project structure
pytorrent/ Application package
pytorrent/routes/ Flask routes and API modules
pytorrent/services/ rTorrent, planner, queue and helper services
pytorrent/static/ Frontend JavaScript and CSS
pytorrent/templates/ HTML templates
scripts/ Installers and maintenance tools
systemd/ systemd service files
data/ Runtime data directory
License
AGPL-3
