<!-- Thanks for opening a PR! Your contribution is much appreciated. In order to make sure your PR is handled as smoothly as possible we request that you follow the checklist sections below. Choose the right checklist for the change that you're making: --> ## Description Add `--host` / `-H` CLI argument to allow users to specify the host address the UI should bind to. This allows for more flexibility so people can bind only to `127.0.0.1` for example instead of the default of `0.0.0.0` which exposes all interfaces. Fixes # N/A ## Type of change - [x] New feature (non-breaking change which adds functionality) - [x] This change requires a documentation update ## Checklist: - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my own code - [ ] (N/A) I have commented my code, particularly in hard-to-understand areas - [ ] (N/A) I have added or updated the docstring for new or existing methods - [x] I have modified this PR to merge to the develop branch --------- Co-authored-by: bobokun <12660469+bobokun@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
7.3 KiB
Web API Documentation
Overview
qBit Manage provides a REST API that allows you to trigger commands via HTTP requests. The API server runs at 8080, listening to all hostnames, by default and can be configured using the --host
and --port
options or QBT_HOST
and QBT_PORT
environment variables.
Running the Web Server
Command Line
python qbit_manage.py --web-server --host 0.0.0.0 --port 8080
Docker
version: "3"
services:
qbit_manage:
image: bobokun/qbit_manage:latest
container_name: qbit_manage
environment:
- QBT_WEB_SERVER=true # Enable web server
- QBT_HOST=0.0.0.0 # Set web server host
- QBT_PORT=8080 # Set web server port
ports:
- "8080:8080" # Map container port to host
volumes:
- /path/to/config:/config
API Endpoints
POST /api/run-command
Execute qBit Manage commands via the API.
Request Body
{
"config_file": "config.yml", // Optional, defaults to "config.yml"
"commands": ["cat_update", "tag_update"], // Required, list of commands to run
"hashes": ["<hash1>", "<hash2>"], // Optional, list of torrent hashes to filter by
"dry_run": false, // Optional, defaults to false
"skip_cleanup": false, // Optional, defaults to false
"skip_qb_version_check": false, // Optional, defaults to false
"log_level": null // Optional, defaults to null (e.g., "info", "debug", "error")
}
Response
Success:
{
"status": "success",
"message": "Commands executed successfully for all configs",
"results": [
{
"config_file": "config.yml",
"stats": {
"executed_commands": ["cat_update", "tag_update"],
"categorized": 5,
"tagged": 10
}
}
]
}
Queued (when scheduled run is in progress):
{
"status": "queued",
"message": "Scheduled run in progress. Request queued.",
"config_file": "config.yml",
"commands": ["cat_update", "tag_update"]
}
Error:
{
"detail": "Error message"
}
Available Commands
The following commands can be included in the commands
array of the API request:
Command | Description | Supports Hashes |
---|---|---|
cat_update |
Update categories based on save paths | Yes |
tag_update |
Add tags based on tracker URLs | Yes |
recheck |
Recheck paused torrents sorted by size and resume completed ones | Yes |
rem_unregistered |
Remove unregistered torrents | Yes |
tag_tracker_error |
Tag torrents with tracker errors | Yes |
rem_orphaned |
Remove orphaned files from root directory | No |
tag_nohardlinks |
Tag torrents with no hard links | Yes |
share_limits |
Apply share limits based on tags/categories | Yes |
Example using multiple commands:
{
"config_file": "config.yml",
"commands": ["cat_update", "tag_update", "share_limits"],
"dry_run": true
}
qBittorrent Integration
qBittorrent can call a program after a torrent is added or finished. You can configure this in Settings > Downloads > Run external program
.
Example command to run after torrent added/finished:
#!/bin/bash
# run_qbit_manage_commands.sh
#
# Sends a POST request to qBit Manage with a given torrent hash to trigger
# actions like "tag_update" and "share_limits".
#
# USAGE:
# ./run_qbit_manage_commands.sh <torrent_hash>
#
# EXAMPLE:
# ./run_qbit_manage_commands.sh 123ABC456DEF789XYZ
#
# NOTES:
# - Make sure this script is executable: chmod +x run_qbit_manage_commands.sh
# - The torrent hash is typically passed in automatically by qBittorrent via the "%I" variable.
# - All output is logged to run_qbit_manage_commands.log in the same directory as the script,
# and also printed to stdout.
set -euo pipefail
API_URL="http://qbit_manage:8080/api/run-command"
COMMANDS='["tag_update", "share_limits"]'
if [[ $# -lt 1 || -z "$1" ]]; then
echo "Usage: $0 <torrent_hash>" >&2
exit 1
fi
TORRENT_HASH="$1"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
LOG_FILE="${SCRIPT_DIR}/run_qbit_manage_commands.log"
JSON="{\"commands\":${COMMANDS},\"hashes\":[\"${TORRENT_HASH}\"]}"
{
echo "Sending API call for hash: ${TORRENT_HASH}"
echo "Payload: ${JSON}"
} | tee -a "${LOG_FILE}"
if curl -fsSL -X POST \
-H "Content-Type: application/json" \
-d "${JSON}" \
"${API_URL}" | tee -a "${LOG_FILE}"; then
echo "Success" | tee -a "${LOG_FILE}"
else
echo "Error: qBit Manage API call failed for hash ${TORRENT_HASH}" | tee -a "${LOG_FILE}"
fi
To use this script:
- Save it as a file (e.g.,
run_qbit_manage_commands.sh
). - Make the script executable:
chmod +X /path/to/run_qbit_manage_commands.sh
- In qBittorrent, configure
Settings > Downloads > Run external program
to execute this script, passing%I
as an argument:
The script will create a log file named/path/to/run_qbit_manage_commands.sh "%I"
run_qbit_manage_commands.log
in the same directory where the script is located.
Behavior
-
Concurrent Execution:
- API requests during scheduled runs are automatically queued
- Queued requests are processed after the scheduled run completes
- Double-check mechanism prevents race conditions
-
Command Execution:
- Commands sent to the API are mandatory and the commands defined in ENV variables and in the config file are not used when using the API.
- All regular command validations apply
- Dry run mode available for testing
-
Error Handling:
- Failed requests return appropriate error messages
- Queue state is preserved even during errors
- Proper cleanup ensures system stability
Example Usage
Using curl:
curl -X POST http://localhost:8080/api/run-command \
-H "Content-Type: application/json" \
-d '{
"config_file": "config.yml",
"commands": ["cat_update", "tag_update"],
"hashes": ["a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0"],
"dry_run": false,
"skip_cleanup": false,
"skip_qb_version_check": false,
"log_level": "info"
}'
Using Python requests:
import requests
response = requests.post(
"http://localhost:8080/api/run-command",
json={
"config_file": "config.yml",
"commands": ["cat_update", "tag_update"],
"hashes": ["a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0"],
"dry_run": False,
"skip_cleanup": False,
"skip_qb_version_check": False,
"log_level": "info"
}
)
print(response.json())
Command Validation
- All commands must be valid command names from the list above
- Commands are case-sensitive
- Invalid commands will return a 400 error with detail about the invalid command
- Empty command list will return a 400 error
- Commands defined in ENV variables or config files are ignored when using the API
- The API validates commands before execution and during runtime
Example error response for invalid command:
{
"detail": "Invalid command: invalid_command"
}