QBITTORRENT-API(1)
π QBITTORRENT-API π β like, the qbittorrent-api manual, bestie
okay so first things first, this is the man page for qbittorrent-api β version 2026.5.0, no cap π
github ci codecov
pypi pypi versions pypi downloads
It's a Python client implementation for qBittorrent Web API. πβ¨
Right now it supports qBittorrent v5.2.0 (that's Web API v2.15.1) which dropped on May 03, 2026. iconic behavior honestly.
β¨ FEATURES β¨
- The entire qBittorrent Web API is implemented. the whole thing. every last crumb π
- qBittorrent version checking for an endpoint's existence/features is automatically handled β you don't gotta do a thing, it just knows π§
- If the authentication cookie expires, a new one is automatically requested in line with any API call. self-healing king π
π INSTALLATION π
- Install via pip from PyPI:
python -m pip install qbittorrent-api
- Install a specific release (e.g. v2024.3.60):
python -m pip install qbittorrent-api==2024.3.60
- Install direct from main:
pip install git+https://github.com/rmartin14/qbittorrent-api.git@main#egg=qbittorrent-api
- Enable WebUI in qBittorrent: Tools -> Preferences -> Web UI π
- If the Web API will be exposed to the Internet, follow the
s-Encrypt-certificates-and-NGINX-SSL-reverse-proxy'recommendations.
πΈ GETTING STARTED πΈ
k so here's the whole vibe in one go π«Ά
import qbittorrentapi
# instantiate a Client using the appropriate WebUI configuration
conn_info = dict(
host="localhost",
port=8080,
username="admin",
password="adminadmin",
)
qbt_client = qbittorrentapi.Client(**conn_info)
# the Client will automatically acquire/maintain a logged-in state
# in line with any request. therefore, this is not strictly necessary;
# however, you may want to test the provided login credentials.
try:
qbt_client.auth_log_in()
except qbittorrentapi.LoginFailed as e:
print(e)
# if the Client will not be long-lived or many Clients may be created
# in a relatively short amount of time, be sure to log out:
qbt_client.auth_log_out()
# or use a context manager:
with qbittorrentapi.Client(**conn_info) as qbt_client:
if qbt_client.torrents_add(urls="...") != "Ok.":
raise Exception("Failed to add torrent.")
# display qBittorrent info
print(f"qBittorrent: {qbt_client.app.version}")
print(f"qBittorrent Web API: {qbt_client.app.web_api_version}")
for k, v in qbt_client.app.build_info.items():
print(f"{k}: {v}")
# retrieve and show all torrents
for torrent in qbt_client.torrents_info():
print(f"{torrent.hash[-6:]}: {torrent.name} ({torrent.state})")
# stop all torrents
qbt_client.torrents.stop.all()
she's beauty, she's grace, she stops all torrents at once π
π¦ USAGE π¦
Okay so first β the Web API endpoints are organized into eight namespaces. eight! count 'em:
- Authentication (
auth) - Application (
app) - Log (
log) - Sync (
sync) - Transfer (
transfer) - Torrent Management (
torrents) - RSS (
rss) - Search (
search)
Second β this client has two modes of interaction with the qBittorrent Web API.
Each Web API endpoint is implemented one-to-one as a method of the instantiated client. so like, direct. no middleman.
import qbittorrentapi
qbt_client = qbittorrentapi.Client(host='localhost:8080', username='admin', password='adminadmin')
qbt_client.app_version()
qbt_client.rss_rules()
qbt_client.torrents_info()
qbt_client.torrents_resume(torrent_hashes='...')
# and so on
However β a more robust interface to the endpoints is available via each namespace. This is intended to provide a more seamless and intuitive interface to the Web API. it's giving glow-up β¨
import qbittorrentapi
qbt_client = qbittorrentapi.Client(host='localhost:8080', username='admin', password='adminadmin')
# changing a preference
is_dht_enabled = qbt_client.app.preferences.dht
qbt_client.app.preferences = dict(dht=not is_dht_enabled)
# stopping all torrents
qbt_client.torrents.stop.all()
# retrieve different views of the log
qbt_client.log.main.warning()
qbt_client.log.main.normal()
Finally β some of the objects returned by the client support methods of their own. This is most pronounced for torrents themselves. they're literally main characters at this point π
import qbittorrentapi
qbt_client = qbittorrentapi.Client(host='localhost:8080', username='admin', password='adminadmin')
for torrent in qbt_client.torrents.info.active():
torrent.set_location(location='/home/user/torrents/')
torrent.reannounce()
torrent.upload_limit = -1
π« Introduction π«
github ci codecov
pypi pypi versions pypi downloads
Python client implementation for qBittorrent Web API. that's the whole pitch fr fr π«Ά
Currently supports qBittorrent v5.2.0 (Web API v2.15.1) released on May 03, 2026.
π₯ Features π₯
- The entire qBittorrent Web API is implemented. all of it. nothing left on read π
- qBittorrent version checking for an endpoint's existence/features is automatically handled. she checks herself, you don't gotta worry π
- If the authentication cookie expires, a new one is automatically requested in line with any API call. auto-relogin, we love to see it β
π Installation π
- Install via pip from PyPI:
python -m pip install qbittorrent-api
- Install a specific release (e.g. v2024.3.60):
python -m pip install qbittorrent-api==2024.3.60
- Install direct from main:
pip install git+https://github.com/rmartin14/qbittorrent-api.git@main#egg=qbittorrent-api
- Enable WebUI in qBittorrent: Tools -> Preferences -> Web UI
- If the Web API will be exposed to the Internet, follow the
s-Encrypt-certificates-and-NGINX-SSL-reverse-proxy'recommendations.
bestie, read that last one again. if the Web API is gonna be on the Internet, do the recommendation thing. don't just vibe and hope π
π Getting Started π
import qbittorrentapi
# instantiate a Client using the appropriate WebUI configuration
conn_info = dict(
host="localhost",
port=8080,
username="admin",
password="adminadmin",
)
qbt_client = qbittorrentapi.Client(**conn_info)
# the Client will automatically acquire/maintain a logged-in state
# in line with any request. therefore, this is not strictly necessary;
# however, you may want to test the provided login credentials.
try:
qbt_client.auth_log_in()
except qbittorrentapi.LoginFailed as e:
print(e)
# if the Client will not be long-lived or many Clients may be created
# in a relatively short amount of time, be sure to log out:
qbt_client.auth_log_out()
# or use a context manager:
with qbittorrentapi.Client(**conn_info) as qbt_client:
if qbt_client.torrents_add(urls="...") != "Ok.":
raise Exception("Failed to add torrent.")
# display qBittorrent info
print(f"qBittorrent: {qbt_client.app.version}")
print(f"qBittorrent Web API: {qbt_client.app.web_api_version}")
for k, v in qbt_client.app.build_info.items():
print(f"{k}: {v}")
# retrieve and show all torrents
for torrent in qbt_client.torrents_info():
print(f"{torrent.hash[-6:]}: {torrent.name} ({torrent.state})")
# stop all torrents
qbt_client.torrents.stop.all()
π§ Usage π§
First, the Web API endpoints are organized in to eight namespaces:
- Authentication (
auth) - Application (
app) - Log (
log) - Sync (
sync) - Transfer (
transfer) - Torrent Management (
torrents) - RSS (
rss) - Search (
search)
Second, this client has two modes of interaction with the qBittorrent Web API.
Each Web API endpoint is implemented one-to-one as a method of the instantiated client:
import qbittorrentapi
qbt_client = qbittorrentapi.Client(host='localhost:8080', username='admin', password='adminadmin')
qbt_client.app_version()
qbt_client.rss_rules()
qbt_client.torrents_info()
qbt_client.torrents_resume(torrent_hashes='...')
# and so on
However, a more robust interface to the endpoints is available via each namespace. This is intended to provide a more seamless and intuitive interface to the Web API:
import qbittorrentapi
qbt_client = qbittorrentapi.Client(host='localhost:8080', username='admin', password='adminadmin')
# changing a preference
is_dht_enabled = qbt_client.app.preferences.dht
qbt_client.app.preferences = dict(dht=not is_dht_enabled)
# stopping all torrents
qbt_client.torrents.stop.all()
# retrieve different views of the log
qbt_client.log.main.warning()
qbt_client.log.main.normal()
Finally, some of the objects returned by the client support methods of their own. This is most pronounced for torrents themselves:
import qbittorrentapi
qbt_client = qbittorrentapi.Client(host='localhost:8080', username='admin', password='adminadmin')
for torrent in qbt_client.torrents.info.active():
torrent.set_location(location='/home/user/torrents/')
torrent.reannounce()
torrent.upload_limit = -1
π Behavior & Configuration π
π Host, Username and Password π
- The authentication credentials can be provided when instantiating
Client:
qbt_client = Client(host="localhost:8080", username='...', password='...')
- The credentials can also be specified after
Clientis created but callingauth_log_in()is not strictly necessary to authenticate the client; this will happen automatically for any API request.
qbt_client.auth_log_in(username='...', password='...')
- Alternatively, the credentials can be specified in environment variables:
QBITTORRENTAPI_HOSTQBITTORRENTAPI_USERNAMEQBITTORRENTAPI_PASSWORD
pick your fighter: inline args, post-instantiation, or env vars. all three ate π
π qBittorrent Session Management π
- Any time a connection is established with qBittorrent, it instantiates a session to manage authentication for all subsequent API requests.
- This client will transparently manage sessions by ensuring the client is always logged in in-line with any API request including requesting a new session upon expiration of an existing session. lowkey the best part π«Ά
- However, each new
Clientinstantiation will create a new session in qBittorrent. - Therefore, if many
Clientinstances will be created be sure to callauth_log_outfor each instance or use a context manager. - Otherwise, qBittorrent may experience abnormally high memory usage.
π¨ no like seriously. if you're spawning a bunch of Clients and not logging out, qBittorrent's memory usage goes off the rails. that's not a vibe.
with qbittorrentapi.Client(**conn_info) as qbt_client:
if qbt_client.torrents_add(urls="...") != "Ok.":
raise Exception("Failed to add torrent.")
π¦ Untrusted Web API Certificate π¦
- qBittorrent allows you to configure HTTPS with an untrusted certificate; this commonly includes self-signed certificates.
- When using such a certificate, instantiate
ClientwithVERIFY_WEBUI_CERTIFICATE=Falseor set environment variableQBITTORRENTAPI_DO_NOT_VERIFY_WEBUI_CERTIFICATEto a non-null value. - Failure to do this for will cause connections to qBittorrent to fail.
π yes, it really will just fail. self-signed cert + default settings = sadness. flip that flag, bestie.
- As a word of caution, doing this actually does turn off certificate verification. So bestie, take note: potential man-in-the-middle attacks will not be detected and reported (since the error is suppressed). Lowkey scary. The one silver lining? The connection will remain encrypted. π«Ά
qbt_client = Client(..., VERIFY_WEBUI_CERTIFICATE=False}
π Requests Configuration
- The
Requestspackage is used to issue HTTP requests to qBittorrent to facilitate this API. It's the whole engine, basically. - Much of Requests configuration for making HTTP requests can be controlled with parameters passed along with the request payload.
- For instance, HTTP Basic Authorization credentials can be provided via
auth, timeouts viatimeout, or Cookies viacookies. See Requests documentation for full details. - These parameters are exposed here in two ways; the examples below tell Requests to use a connect timeout of
3.1seconds and a read timeout of30seconds. The way that works is honestly so clean. β¨ - When you instantiate
Client, you can specify the parameters to use in all HTTP requests to qBittorrent:
qbt_client = Client(..., REQUESTS_ARGS={'timeout': (3.1, 30)}
- Alternatively, parameters can be specified for individual requests:
qbt_client.torrents_info(..., requests_args={'timeout': (3.1, 30)})
- Additionally, configuration for the
HTTPAdapterfor theSessioncan be specified via theHTTPADAPTER_ARGSparameter forClient:
qbt_client = Client(..., HTTPADAPTER_ARGS={"pool_connections": 100, "pool_maxsize": 100}
π¨ Additional HTTP Headers
- For consistency, HTTP Headers can be specified using the method above; for backwards compatibility, the methods below are supported as well. Bestie, the legacy support is such a slay. π
- Either way, these additional headers will be incorporated (using clobbering) into the rest of the headers to be sent. Clobbering, yes β that's the whole point, they overwrite.
- To send a custom HTTP header in all requests made from an instantiated client, declare them during instantiation:
qbt_client = Client(..., EXTRA_HEADERS={'X-My-Fav-Header': 'header value')
- Alternatively, you can send custom headers in individual requests:
qbt_client.torrents.add(..., headers={'X-My-Fav-Header': 'header value')
π§ Unimplemented API Endpoints
- Since the qBittorrent Web API has evolved over time, some endpoints may not be available from the qBittorrent host. It's giving "your host is on an older season of the show." π
- By default, if a request is made to endpoint that doesn't exist for the version of the qBittorrent host (e.g., the Search endpoints were introduced in Web API
v2.1.1), there's a debug logger output andNoneis returned. - To raise
NotImplementedErrorinstead, instantiateClientwith:
qbt_client = Client(..., RAISE_NOTIMPLEMENTEDERROR_FOR_UNIMPLEMENTED_API_ENDPOINTS=True)
π qBittorrent Version Checking
- It is also possible to either raise an
Exceptionfor qBittorrent hosts that are not "fully" supported or manually check for support. - The most likely situation for this to occur is if the qBittorrent team publishes a new release but its changes have not been incorporated in to this client yet. Like, they dropped new content and this client is still catching up fr fr.
- Instantiate
Clientlike below to raiseUnsupportedQbittorrentVersionexception for versions not fully supported:
qbt_client = Client(..., RAISE_ERROR_FOR_UNSUPPORTED_QBITTORRENT_VERSIONS=True)
- Additionally,
Versioncan be used for manual introspection of the versions.
Version.is_app_version_supported(qbt_client.app.version)
π Disable Logging Debug Output
- Instantiate
ClientwithDISABLE_LOGGING_DEBUG_OUTPUT=Trueor manually disable logging for the relevant packages:
logging.getLogger('qbittorrentapi').setLevel(logging.INFO)
logging.getLogger('requests').setLevel(logging.INFO)
logging.getLogger('urllib3').setLevel(logging.INFO)
β‘ Async Support
qbittorrentapi does not support Python's async/await functionality for asynchronous programming. However, many use-cases for this client operate within an existing asynchronous application. Therefore, in lieu of being able to await this client's API calls to qBittorrent, it is still possible to call them without blocking. Okay so this is lowkey the most important part β you don't have to give up on async, you just have to be clever about it. π§ β¨
Each asyncio Event Loop provides a ThreadPoolExecutor that can run blocking code that could interfere with async applications. In Python 3.9, a simple interface was introduced in asyncio to run synchronous code in this thread pool.
async def fetch_torrents() -> TorrentInfoList:
return await asyncio.to_thread(qbt_client.torrents_info, category="uploaded")
In this example, you simply specify the method to call, torrents_info, as the first argument and follow it with the arguments for the method to run in the thread.
Below is a full example demonstrating this that can be run in the Python REPL:
import asyncio
import qbittorrentapi
qbt_client = qbittorrentapi.Client()
async def fetch_qbt_info():
return await asyncio.to_thread(qbt_client.app_build_info)
print(asyncio.run(fetch_qbt_info()))
ποΈ Performance
By default, complex objects are returned from some endpoints. These objects allow for accessing the response's items as attributes and include methods for contextually relevant actions (such as start() and stop() for a torrent, for example). So cute, so convenient. π
This comes at the cost of performance, though. Generally, this cost isn't large; however, some endpoints, such as torrents_files(), may need to convert a large payload and the cost can be significant. That's the tradeoff, bestie β vibes vs. speed.
This client can be configured to always return only the simple JSON if desired. Simply set SIMPLE_RESPONSES=True when instantiating the client.
qbt_client = qbittorrentapi.Client(
host='localhost:8080',
username='admin',
password='adminadmin',
SIMPLE_RESPONSES=True,
)
Alternatively, SIMPLE_RESPONSES can be set to True to return the simple JSON only for an individual method call.
qbt_client.torrents.files(torrent_hash='...', SIMPLE_RESPONSES=True)
π Exceptions
Okay so here's the full drama chart of everything this client can throw at you. Know them, love them, catch them. π
exception APIErrorβ Bases:Exception. Base error for all exceptions from this Client.exception UnsupportedQbittorrentVersionβ Bases:APIError. Connected qBittorrent is not fully supported by this Client.exception FileErrorβ Bases:OSError,APIError. Base class for all exceptions for file handling.exception TorrentFileErrorβ Bases:FileError. Base class for all exceptions for torrent files.exception TorrentFileNotFoundErrorβ Bases:TorrentFileError. Specified torrent file does not appear to exist.exception TorrentFilePermissionErrorβ Bases:TorrentFileError. Permission was denied to read the specified torrent file.exception APIConnectionError(*args, **kwargs)β Bases:RequestException,APIError. Base class for all communications errors including HTTP errors.exception LoginFailed(*args, **kwargs)β Bases:APIConnectionError. This can technically be raised with any request since log in may be attempted for any request and could fail.exception HTTPError(*args, **kwargs)β Bases:HTTPError,APIConnectionError. Base error for all HTTP errors. All errors following a successful connection to qBittorrent are returned as HTTP statuses. Hashttp_status_code: int.exception HTTP4XXError(*args, **kwargs)β Bases:HTTPError. Base error for all HTTP4XXstatuses.exception HTTP5XXError(*args, **kwargs)β Bases:HTTPError. Base error for all HTTP5XXstatuses.exception HTTP400Error(*args, **kwargs)β Bases:HTTP4XXError. HTTP400Status.http_status_code: int = 400.exception HTTP401Error(*args, **kwargs)β Bases:HTTP4XXError. HTTP401Status.http_status_code: int = 401.exception HTTP403Error(*args, **kwargs)β Bases:HTTP4XXError. HTTP403Status.http_status_code: int = 403.exception HTTP404Error(*args, **kwargs)β Bases:HTTP4XXError. HTTP404Status.http_status_code: int = 404.exception HTTP405Error(*args, **kwargs)β Bases:HTTP4XXError. HTTP405Status.http_status_code: int = 405.exception HTTP409Error(*args, **kwargs)β Bases:HTTP4XXError. HTTP409Status.http_status_code: int = 409.exception HTTP415Error(*args, **kwargs)β Bases:HTTP4XXError. HTTP415Status.http_status_code: int = 415.exception HTTP500Error(*args, **kwargs)β Bases:HTTP5XXError. HTTP500Status.http_status_code: int = 500.exception MissingRequiredParameters400Error(*args, **kwargs)β Bases:HTTP400Error. Endpoint call is missing one or more required parameters.exception InvalidRequest400Error(*args, **kwargs)β Bases:HTTP400Error. One or more endpoint arguments are malformed.exception Unauthorized401Error(*args, **kwargs)β Bases:HTTP401Error. Primarily reserved for XSS and host header issues.exception Forbidden403Error(*args, **kwargs)β Bases:HTTP403Error. Not logged in, IP has been banned, or calling an API method that isn't public.exception NotFound404Error(*args, **kwargs)β Bases:HTTP404Error. This should mean qBittorrent couldn't find a torrent for the torrent hash.exception MethodNotAllowed405Error(*args, **kwargs)β Bases:HTTP405Error. HTTP method is not supported for the API endpoint.exception Conflict409Error(*args, **kwargs)β Bases:HTTP409Error. Returned if arguments don't make sense specific to the endpoint.exception UnsupportedMediaType415Error(*args, **kwargs)β Bases:HTTP415Error.torrents/addendpoint will return this for invalid URL(s) or files.exception InternalServerError500Error(*args, **kwargs)β Bases:HTTP500Error. Returned if qBittorrent errors internally while processing the request.
π API Reference
πΈ Application
class AppAPIMixIn(host=None, port=None, username=None, password=None,
EXTRA_HEADERS=None, REQUESTS_ARGS=None, HTTPADAPTER_ARGS=None,
VERIFY_WEBUI_CERTIFICATE=True, FORCE_SCHEME_FROM_HOST=False,
RAISE_NOTIMPLEMENTEDERROR_FOR_UNIMPLEMENTED_API_ENDPOINTS=False,
RAISE_ERROR_FOR_UNSUPPORTED_QBITTORRENT_VERSIONS=False,
VERBOSE_RESPONSE_LOGGING=False, SIMPLE_RESPONSES=False,
DISABLE_LOGGING_DEBUG_OUTPUT=False) -> None
Bases: AuthAPIMixIn
Implementation of all Application API methods. This is the main character of the whole API, ngl. π
Usage
>>> from qbittorrentapi import Client
>>> client = Client(host="localhost:8080", username="admin", password="adminadmin")
>>> client.app_version()
>>> client.app_preferences()
okay so those are, like, the vibe of the app endpoints β here's every single one of them, no skips π
πΈ app_build_info(**kwargs) -> BuildInfoDictionary
Grabs the qBittorrent build info, bestie. The receipts on what you're running.
<i>This method was introduced with qBittorrent v4.2.0 (Web API v2.3).</i>
- Return type:
BuildInfoDictionary
π app_cookies(**kwargs) -> CookieList
Retrieve the current cookies. That's it, that's the whole job πͺ
- Return type:
CookieList
π app_default_save_path(**kwargs) -> str
The default path where torrents are saved. Like, where your downloads actually land.
- Return type:
str
π¦ app_get_directory_content(directory_path=None, with_metadata=None) -> DirectoryContentList
Shows you the contents of a directory file path. lil peek inside the folder β¨
Raises NotFound404Error β file path not found or not a directory π
Parameters:
directory_path(str | PathLike[AnyStr] | None) β file system path to directorywith_metadata(bool | None) β include file/directory metadata- Return type:
DirectoryContentList
π app_network_interface_address_list(interface_name='', **kwargs) -> NetworkInterfaceAddressList
The addresses for a network interface; omit the name and you get all the addresses. literally all of them.
<i>This method was introduced with qBittorrent v4.2.0 (Web API v2.3).</i>
Parameters:
interface_name(str) β Name of interface to retrieve addresses for- Return type:
NetworkInterfaceAddressList
π app_network_interface_list(**kwargs) -> NetworkInterfaceList
The list of network interfaces on the host. full roster, main character energy π
<i>This method was introduced with qBittorrent v4.2.0 (Web API v2.3).</i>
- Return type:
NetworkInterfaceList
π§ app_preferences(**kwargs) -> ApplicationPreferencesDictionary
Retrieve qBittorrent application preferences. the whole settings vibe check.
- Return type:
ApplicationPreferencesDictionary
β app_send_test_email() -> None
Sends a test email using the configured email address. yes bestie, a test email, we're checking the vibes of your SMTP setup π§
- Return type:
None
π₯ app_set_cookies(cookies=None, **kwargs) -> None
Set cookies. here's the shape they want:
cookies = [
{
'domain': 'example.com',
'path': '/example/path',
'name': 'cookie name',
'value': 'cookie value',
'expirationDate': 1729366667,
},
]
Parameters:
cookies(CookieList | Sequence[Mapping[str, str | int]] | None) β list of cookies to set- Return type:
None
π app_set_preferences(prefs=None, **kwargs) -> None
Set one or more preferences in the qBittorrent application. one pref or twenty, she doesn't care.
Parameters:
prefs(ApplicationPreferencesDictionary | Mapping[str, Any] | None) β dictionary of preferences to set- Return type:
None
π app_shutdown(**kwargs) -> None
Shutdown qBittorrent. bye bestie π
- Return type:
None
π app_version(**kwargs) -> str
The qBittorrent application version. the number, the whole personality.
- Return type:
str
π«Ά app_web_api_version(**kwargs) -> str
The qBittorrent Web API version. different number, still iconic.
- Return type:
str
π class Application(*args, client, **kwargs)
Allows interaction with Application API endpoints. it's the same stuff, just dressed up as a class π
Usage:
>>> from qbittorrentapi import Client
>>> client = Client(host="localhost:8080", username="admin", password="adminadmin")
>>> # these are all the same attributes that are available as named in the
>>> # endpoints or the more pythonic names in Client (with or without 'app_' prepended)
>>> webapiVersion = client.application.webapiVersion
>>> web_api_version = client.application.web_api_version
>>> app_web_api_version = client.application.web_api_version
>>> # access and set preferences as attributes
>>> is_dht_enabled = client.application.preferences.dht
>>> # supports sending a just subset of preferences to update
>>> client.application.preferences = dict(dht=(not is_dht_enabled))
>>> prefs = client.application.preferences
>>> prefs["web_ui_clickjacking_protection_enabled"] = True
>>> client.app.preferences = prefs
>>>
>>> client.application.shutdown()
okay so every single attribute and method on this class, here we go β¨
property build_info: BuildInfoDictionary
Implements app_build_info().
property cookies: CookieList
Implements app_cookies().
property default_save_path: str
Implements app_default_save_path().
get_directory_content(directory_path=None, with_metadata=None) -> DirectoryContentList
Implements app_get_directory_content().
- Return type:
DirectoryContentList
network_interface_address_list(interface_name='', **kwargs) -> NetworkInterfaceAddressList
Implements app_network_interface_address_list().
- Return type:
NetworkInterfaceAddressList
property network_interface_list: NetworkInterfaceList
Implements app_network_interface_list().
property preferences: ApplicationPreferencesDictionary
Implements app_preferences().
send_test_email() -> None
Implements app_send_test_email().
- Return type:
None
set_cookies(cookies=None, **kwargs) -> None
Implements app_set_cookies().
- Return type:
None
set_preferences(prefs=None, **kwargs) -> None
Implements app_set_preferences().
- Return type:
None
shutdown(**kwargs) -> None
Implements app_shutdown().
- Return type:
None
property version: str
Implements app_version().
property web_api_version: str
Implements app_web_api_version().
π§Έ class ApplicationPreferencesDictionary(data=None, **kwargs)
Bases: Dictionary[None | int | str | bool | Sequence[JsonValueT] | Mapping[str, JsonValueT]]
Response for app_preferences(). this is the container your prefs live in π
Definition: https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-5.0)#user-content-get-application-preferences
π¦’ class BuildInfoDictionary(data=None, **kwargs)
Bases: Dictionary[str | int]
Response for app_build_info().
Definition: https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-5.0)#user-content-get-build-info
π· class DirectoryContentList(list_entries, client=None)
Bases: List[str | ListEntry]
Response for app_get_directory_content().
π class Cookie(data=None, **kwargs)
Bases: ListEntry
Item in CookieList. one lil cookie πͺ
π¬ class CookieList(list_entries, client=None)
Bases: List[Cookie]
Response for app_cookies().
π class NetworkInterfaceList(list_entries, client=None)
Bases: List[NetworkInterface]
Response for app_network_interface_list().
πͺ class NetworkInterface(data=None, **kwargs)
Bases: ListEntry
Item in NetworkInterfaceList.
π«§ class NetworkInterfaceAddressList(list_entries, client=None)
Bases: List[str]
Response for app_network_interface_address_list().
πΌ AttrDict (internal)
Copyright (c) 2013 Brendan Curran-Johnson
class AttrDict(*args, **kwargs) -> None
Bases: dict[str, V], MutableAttr[V]
A dict that implements MutableAttr. yes it's a dict, no it doesn't behave like a boring one π
class MutableAttr
Bases: Attr[str, V], MutableMapping[str, V], ABC
A mixin mapping class that allows for attribute-style access of values. so like thing.value instead of thing["value"] β¨
class Attr
Bases: Mapping[K, V], ABC
A mixin class for a mapping that allows for attribute-style access of values.
A key may be used as an attribute if:
- It is a string
- It matches
^[A-Za-z][A-Za-z0-9_]*$(i.e., a public attribute) - The key doesn't overlap with any class attributes (for
Attr, those would beget,items,keys,values,mro, andregister).
If a value which is accessed as an attribute is a Sequence-type (and is not a string/bytes), it will be converted to a _sequence_type with any mappings within it converted to Attrs.
NOTE: This means that if_sequence_typeis notNone, then a sequence accessed as an attribute will be a different object than if accessed as an attribute than if it is accessed as an item. π ngl read that one twice, it matters.
π Authentication
π«Ά class AuthAPIMixIn(...) -> None
here's the full signature verbatim, bestie, all fourteen-ish args, don't skip:
class AuthAPIMixIn(host=None, port=None, username=None, password=None, EXTRA_HEADERS=None, REQUESTS_ARGS=None, HTTPADAPTER_ARGS=None, VERIFY_WEBUI_CERTIFICATE=True, FORCE_SCHEME_FROM_HOST=False, RAISE_NOTIMPLEMENTEDERROR_FOR_UNIMPLEMENTED_API_ENDPOINTS=False, RAISE_ERROR_FOR_UNSUPPORTED_QBITTORRENT_VERSIONS=False, VERBOSE_RESPONSE_LOGGING=False, SIMPLE_RESPONSES=False, DISABLE_LOGGING_DEBUG_OUTPUT=False) -> None
Bases: Request
Implementation of all Authorization API methods. this is the one that gets you in the door πͺβ¨
Usage:
>>> from qbittorrentapi import Client
>>> client = Client(host="localhost:8080", username="admin", password="adminadmin")
>>> _ = client.is_logged_in
>>> client.auth_log_in(username="admin", password="adminadmin")
>>> client.auth_log_out()
π auth_log_in(username=None, password=None, **kwargs) -> None
Okay so this is the one that literally gets you in β it logs you in to the qBittorrent host. That's the whole job bestie π
Raises β things that can go wrong, and they will:
LoginFailedβ if the credentials failed to log in πForbidden403Errorβ if the user is banned... or not logged in π
Parameters
- username (
str | None) β the username for the qBittorrent client - password (
str | None) β the password for the qBittorrent client
Return type: None
π auth_log_out(**kwargs) -> None
Ends the session with qBittorrent. Bye bye, ghosting the server, no hard feelings π«Ά
Return type: None
π΅οΈ property is_logged_in: bool
Returns True if a low-overhead API call succeeds; False otherwise.
And here's the tea, no cap: there is no reliable way to know if an existing session is still valid without actually attempting to use it. qBittorrent invalidates cookies when they expire β that's just how it is, we don't make the rules.
Returns: True/False depending on whether the current authorization cookie is accepted by qBittorrent β¨
π class Authorization(*args, client, **kwargs)
Allows interaction with the Authorization API endpoints. It's giving little helper object for auth things.
Usage
>>> from qbittorrentapi import Client
>>> client = Client(host="localhost:8080", username="admin", password="adminadmin")
>>> is_logged_in = client.auth.is_logged_in
>>> client.auth.log_in(username="admin", password="adminadmin")
>>> client.auth.log_out()
property is_logged_in: bool β implements is_logged_in().
log_in(username=None, password=None, **kwargs) -> None β implements auth_log_in(). Return type is None.
log_out(**kwargs) -> None β implements auth_log_out(). Return type is None.
π Client
class Client(host='', port=None, username=None, password=None, *, EXTRA_HEADERS=None, REQUESTS_ARGS=None, HTTPADAPTER_ARGS=None, VERIFY_WEBUI_CERTIFICATE=True, FORCE_SCHEME_FROM_HOST=False, RAISE_NOTIMPLEMENTEDERROR_FOR_UNIMPLEMENTED_API_ENDPOINTS=False, RAISE_ERROR_FOR_UNSUPPORTED_QBITTORRENT_VERSIONS=False, VERBOSE_RESPONSE_LOGGING=False, SIMPLE_RESPONSES=False, DISABLE_LOGGING_DEBUG_OUTPUT=False)
class Client(host='', port=None, username=None, password=None, *,
EXTRA_HEADERS=None, REQUESTS_ARGS=None, HTTPADAPTER_ARGS=None,
VERIFY_WEBUI_CERTIFICATE=True, FORCE_SCHEME_FROM_HOST=False,
RAISE_NOTIMPLEMENTEDERROR_FOR_UNIMPLEMENTED_API_ENDPOINTS=False,
RAISE_ERROR_FOR_UNSUPPORTED_QBITTORRENT_VERSIONS=False,
VERBOSE_RESPONSE_LOGGING=False, SIMPLE_RESPONSES=False,
DISABLE_LOGGING_DEBUG_OUTPUT=False)
Bases: LogAPIMixIn, SyncAPIMixIn, TransferAPIMixIn, TorrentsAPIMixIn, TorrentCreatorAPIMixIn, RSSAPIMixIn, SearchAPIMixIn β yeah she's got a whole inheritance situation going on, main character energy fr fr π
Initializes the API for the qBittorrent client.
Host must be specified. Username and password can be specified at login. And here's the thing β a call to auth_log_in() is not explicitly required if you hand over username and password during Client construction. She'll handle it β¨
Usage
>>> from qbittorrentapi import Client
>>> client = Client(host='localhost:8080', username='admin', password='adminadmin')
>>> torrents = client.torrents_info()
Parameters
- host (
str) β hostname for the qBittorrent Web API, in the form[http[s]://]hostname[:port][/path] - port (
str | int | None) β port number for the qBittorrent Web API (ignored if host contains a port β she said what she said) - username (
str | None) β username for the qBittorrent Web API - password (
str | None) β password for the qBittorrent Web API SIMPLE_RESPONSES(bool) β so by default, complex objects are returned from some endpoints. Those objects let you access the response's items as attributes and include methods for contextually relevant actions. That comes at the cost of performance. Generally the cost isn't large; however, some endpoints, like thetorrents_files()method, may need to convert a large payload. Set this toTrueto get the simple JSON back. Alternatively, set it toTrueonly for an individual method call. For instance, when requesting the files for a torrent:client.torrents_files(torrent_hash='...', SIMPLE_RESPONSES=True)VERIFY_WEBUI_CERTIFICATE(bool) β set toFalseto skip certificate verification for HTTPS connections; for instance, if the connection is using a self-signed certificate. β οΈ Not setting this toFalsefor self-signed certs will cause anAPIConnectionErrorexception to be raised.EXTRA_HEADERS(Mapping[str, str] | None) β dictionary of HTTP headers to include in all requests made to qBittorrentREQUESTS_ARGS(Mapping[str, Any] | None) β dictionary of configuration for each HTTP request made byrequests.requestHTTPADAPTER_ARGS(Mapping[str, Any] | None) β dictionary of configuration forHTTPAdapterFORCE_SCHEME_FROM_HOST(bool) β if a scheme (i.e.httporhttps) is specified inhost, it will be used regardless of whether qBittorrent is configured for HTTP or HTTPS communication. Normally this client will attempt to determine which scheme qBittorrent is actually listening on... but this can cause problems in rare cases. Defaults toFalse.RAISE_NOTIMPLEMENTEDERROR_FOR_UNIMPLEMENTED_API_ENDPOINTS(bool) β some endpoints may not be implemented in older versions of qBittorrent. Setting this toTruewill raise aNotImplementedErrorinstead of just returningNone.RAISE_ERROR_FOR_UNSUPPORTED_QBITTORRENT_VERSIONS(bool) β raiseUnsupportedQbittorrentVersionif the connected version of qBittorrent is not fully supported by this client. Defaults toFalse.DISABLE_LOGGING_DEBUG_OUTPUT(bool) β turns off debug output from logging for this package as well asrequests&urllib3.
π Definitions
APIKwargsT
Type Any for kwargs parameters for API methods. Very demure, very flexible.
class APINames(*values)
Bases: str, Enum
API namespaces for API endpoints.
e.g. torrents in http://localhost:8080/api/v2/torrents/addTrackers π§
Application = 'app'Authorization = 'auth'EMPTY = ''Log = 'log'RSS = 'rss'Search = 'search'Sync = 'sync'TorrentCreator = 'torrentcreator'Torrents = 'torrents'Transfer = 'transfer'
class ClientCache(*args, client, **kwargs)
Bases: Generic[ClientT]
Caches the client. Subclass this for any object that needs access to the Client. It's giving "hold my client" energy π
ClientT
Type for this API Client.
alias of TypeVar('ClientT', bound=Request)
class Dictionary(data=None, **kwargs)
Bases: AttrDict[V]
Base definition of dictionary-like objects returned from qBittorrent. The blueprint, the origin story β¨
FilesToSendT
Type for the Files input to an API method.
alias of Mapping[str, bytes | tuple[str, bytes]]
JsonValueT = None | int | str | bool | collections.abc.Sequence['JsonValueT'] | collections.abc.Mapping[str, 'JsonValueT']
Type to define JSON. Yes she's recursive, yes she ate π
class List(list_entries=None, entry_class=None, **kwargs)
Bases: UserList[ListEntryT]
Base definition for list-like objects returned from qBittorrent.
class ListEntry(data=None, **kwargs)
Bases: Dictionary[None | int | str | bool | Sequence[JsonValueT] | Mapping[str, JsonValueT]]
Base definition for objects within a list returned from qBittorrent. The little guys inside the bigger list π«Ά
ListEntryT
Type for an entry in List from the API.
alias of TypeVar('ListEntryT', bound=ListEntry)
ListInputT
Type for List input to an API method.
alias of Iterable[Mapping[str, None | int | str | bool | Sequence[JsonValueT] | Mapping[str, JsonValueT]]]
class TorrentState(*values)
Bases: str, Enum
Torrent States as defined by qBittorrent. Obsessed with this one ngl, it's the enum you'll actually be using.
Note: in qBittorrent v5.0.0: -PAUSED_UPLOADwas renamed toSTOPPED_UPLOAD-PAUSED_DOWNLOADwas renamed toSTOPPED_DOWNLOAD
Definitions:
- wiki:
https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-5.0)#user-content-get-torrent-list - code:
https://github.com/qbittorrent/qBittorrent/blob/8e6515be2c8cc2b335002ab8913e9dcdd7873204/src/base/bittorrent/torrent.h#L79
Usage
>>> from qbittorrentapi import Client, TorrentState
>>> client = Client()
>>> # print torrent hashes for torrents that are downloading
>>> for torrent in client.torrents_info():
>>> # check if torrent is downloading
>>> if torrent.state_enum.is_downloading:
>>> print(f'{torrent.hash} is downloading...')
>>> # the appropriate enum member can be directly derived
>>> state_enum = TorrentState(torrent.state)
>>> print(f'{torrent.hash}: {state_enum.value}')
Members, in all their glory π₯
ALLOCATING = 'allocating'CHECKING_DOWNLOAD = 'checkingDL'CHECKING_RESUME_DATA = 'checkingResumeData'CHECKING_UPLOAD = 'checkingUP'DOWNLOADING = 'downloading'ERROR = 'error'FORCED_DOWNLOAD = 'forcedDL'FORCED_METADATA_DOWNLOAD = 'forcedMetaDL'FORCED_UPLOAD = 'forcedUP'METADATA_DOWNLOAD = 'metaDL'MISSING_FILES = 'missingFiles'MOVING = 'moving'PAUSED_DOWNLOAD = 'pausedDL'βpausedDLwas renamed tostoppedDLin Web API v2.11.0PAUSED_UPLOAD = 'pausedUP'βpausedUPwas renamed tostoppedUPin Web API v2.11.0QUEUED_DOWNLOAD = 'queuedDL'QUEUED_UPLOAD = 'queuedUP'STALLED_DOWNLOAD = 'stalledDL'STALLED_UPLOAD = 'stalledUP'STOPPED_DOWNLOAD = 'stoppedDL'STOPPED_UPLOAD = 'stoppedUP'UNKNOWN = 'unknown'UPLOADING = 'uploading'property is_checking: boolβ gives youTruewhen the State is categorized as Checking πproperty is_complete: boolβ gives youTruewhen the State is categorized as Complete βproperty is_downloading: boolβ gives youTruewhen the State is categorized as Downloading β¬οΈproperty is_errored: boolβ gives youTruewhen the State is categorized as Errored πproperty is_paused: boolβ literally just an alias ofTorrentState.is_stopped, same vibe different name π«Άproperty is_stopped: boolβ gives youTruewhen the State is categorized as Stopped πproperty is_uploading: boolβ gives youTruewhen the State is categorized as Uploading β¬οΈ
class TrackerStatus(*values)
Bases: int, Enum
Tracker Statuses as defined by qBittorrent, bestie. Here's where they come from:
- wiki: https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-5.0)#user-content-get-torrent-trackers
- code: https://github.com/qbittorrent/qBittorrent/blob/5dcc14153f046209f1067299494a82e5294d883a/src/base/bittorrent/trackerentry.h#L42
Usage β copy this energy β¨
>>> from qbittorrentapi import Client, TrackerStatus
>>> client = Client()
>>> # print torrent hashes for torrents that are downloading
>>> for torrent in client.torrents_info():
>>> for tracker in torrent.trackers:
>>> # display status for each tracker
>>> print(f"{torrent.hash[-6:]}: {TrackerStatus(tracker.status).display:>13} :{tracker.url}")
The actual values, no cap:
DISABLED = 0NOT_CONTACTED = 1NOT_WORKING = 4UPDATING = 3WORKING = 2
property display: str β returns a descriptive display value for status, so you get something cute and readable instead of a sad little number π
π Log
class LogAPIMixIn(host=None, port=None, username=None, password=None, EXTRA_HEADERS=None, REQUESTS_ARGS=None, HTTPADAPTER_ARGS=None, VERIFY_WEBUI_CERTIFICATE=True, FORCE_SCHEME_FROM_HOST=False, RAISE_NOTIMPLEMENTEDERROR_FOR_UNIMPLEMENTED_API_ENDPOINTS=False, RAISE_ERROR_FOR_UNSUPPORTED_QBITTORRENT_VERSIONS=False, VERBOSE_RESPONSE_LOGGING=False, SIMPLE_RESPONSES=False, DISABLE_LOGGING_DEBUG_OUTPUT=False) -> None
Bases: AppAPIMixIn
This is the implementation of all Log API methods β every log endpoint lives here ποΈ
Usage:
>>> from qbittorrentapi import Client
>>> client = Client(host="localhost:8080", username="admin", password="adminadmin")
>>> client.log_main(info=False)
>>> client.log_peers()
log_main(normal=None, info=None, warning=None, critical=None, last_known_id=None, **kwargs) -> LogMainListβ retrieve the qBittorrent log entries. Just iterate over the returned object, it's giving list energy πΈ- normal (
bool | None) βFalseto exclude normal entries - info (
bool | None) βFalseto exclude info entries - warning (
bool | None) βFalseto exclude warning entries - critical (
bool | None) βFalseto exclude critical entries - last_known_id (
str | int | None) β only entries with an ID greater than this value will be returned - Return type:
LogMainList
- normal (
log_peers(last_known_id=None, **kwargs) -> LogPeersListβ retrieve the qBittorrent peer log π«Ά- last_known_id (
str | int | None) β only entries with an ID greater than this value will be returned - Return type:
LogPeersList
- last_known_id (
class Log(client)
Bases: nothing extra, it's just vibes β allows interaction with Log API endpoints.
Usage:
>>> from qbittorrentapi import Client
>>> client = Client(host="localhost:8080", username="admin", password="adminadmin")
>>> # this is all the same attributes that are available as named in the
>>> # endpoints or the more pythonic names in Client (with or without 'log_' prepended)
>>> log_list = client.log.main()
>>> peers_list = client.log.peers(last_known_id="...")
>>> # can also filter log down with additional attributes
>>> log_info = client.log.main.info(last_known_id=1)
>>> log_warning = client.log.main.warning(last_known_id=1)
class Main(*args, client, **kwargs)__call__(normal=True, info=True, warning=True, critical=True, last_known_id=None, **kwargs) -> LogMainListβ implementslog_main().- Return type:
LogMainList
- Return type:
critical(last_known_id=None, **kwargs) -> LogMainListβ implementslog_main()withinfo=False,normal=False, andwarning=False.- Return type:
LogMainList
- Return type:
info(last_known_id=None, **kwargs) -> LogMainListβ implementslog_main().- Return type:
LogMainList
- Return type:
normal(last_known_id=None, **kwargs) -> LogMainListβ implementslog_main()withinfo=False.- Return type:
LogMainList
- Return type:
warning(last_known_id=None, **kwargs) -> LogMainListβ implementslog_main()withinfo=Falseandnormal=False.- Return type:
LogMainList
- Return type:
property main: Mainβ implementslog_main()πpeers(last_known_id=None, **kwargs) -> LogPeersListβ implementslog_peers().- Return type:
LogPeersList
- Return type:
The list/entry girlies π§
class LogPeersList(list_entries, client=None)β bases:List[LogPeer]. This is the response forlog_peers().class LogPeer(data=None, **kwargs)β bases:ListEntry. One single item inLogPeersList.class LogMainList(list_entries, client=None)β bases:List[LogEntry]. This is the response tolog_main().class LogEntry(data=None, **kwargs)β bases:ListEntry. One single item inLogMainList.
π§ Request (internal)
Bestie warning: this whole section is internal β it's the plumbing, not the faucet. Peek if you're curious, but you probably don't need to touch it π«£
class QbittorrentSession
Bases: Session
It's a wrapper to augment the Requests Session. Here's the why: Requests doesn't allow Session to default certain configuration globally, and this gets around that by setting defaults for each request. Iconic workaround behavior, honestly π
request(method, url, **kwargs) -> Response β constructs a Request, prepares it and sends it. Returns a Response object.
- method (
str) β method for the new Request object. - url (
str) β URL for the new Request object. - params β (optional) Dictionary or bytes to be sent in the query string for the Request.
- data β (optional) Dictionary, list of tuples, bytes, or file-like object to send in the body of the Request.
- json β (optional) json to send in the body of the Request.
- headers β (optional) Dictionary of HTTP Headers to send with the Request.
- cookies β (optional) Dict or CookieJar object to send with the Request.
- files β (optional) Dictionary of
'filename': file-like-objects for multipart encoding upload. - auth β (optional) Auth tuple or callable to enable Basic/Digest/Custom HTTP Auth.
- timeout (
float or tuple) β (optional) How many seconds to wait for the server to send data before giving up, as a float, or a(connect timeout, read timeout)tuple. - allow_redirects (
bool) β (optional) Set toTrueby default. - proxies β (optional) Dictionary mapping protocol or protocol and hostname to the URL of the proxy.
- hooks β (optional) Dictionary mapping hook name to one event or list of events, event must be callable.
- stream β (optional) whether to immediately download the response content. Defaults to
False. - verify β (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use. Defaults to
True. When set toFalse, requests will accept any TLS certificate presented by the server, and will ignore hostname mismatches and/or expired certificates, which will make your application vulnerable to man-in-the-middle (MitM) attacks. Setting verify toFalsemay be useful during local development or testing.
π¨ Okay so this one matters: setting verify to False means accepting any TLS certificate, ignoring hostname mismatches and/or expired certificates, which makes your app vulnerable to man-in-the-middle (MitM) attacks. It may be useful during local development or testing β but that's it, bestie. Do not ship that. π
- cert β (optional) if String, path to ssl client cert file (
.pem). If Tuple,('cert', 'key')pair. - Return type:
Response
class QbittorrentURL(client)
Bases: object
Management for the qBittorrent Web API URL β the girl who knows where everything lives πΊοΈ
build(api_namespace, api_method, headers=None, requests_kwargs=None, base_path='api/v2') -> str β create a fully qualified URL for the API endpoint.
- api_namespace (
APINames | str) β the namespace for the API endpoint (e.g. torrents) - api_method (
str) β the specific method for the API endpoint (e.g. info) - base_path (
str) β base path for URL (e.g.api/v2) - headers (
Mapping[str, str] | None) β HTTP headers for request
okay so finishing off that parameter list, bestie:
requests_kwargs(Mapping[str, Any] | None) β kwargs for any calls to Requests
Return type: str
Returns: fully qualified URL string for endpoint
build_base_url
build_base_url(headers, requests_kwargs) -> str
Determine the Base URL for the Web API endpoints.
A URL is only actually built here if itβs the first time here or the context was re-initialized. Otherwise, the most recently built URL is used. no cap, it caches the vibe.
If the user doesnβt provide a scheme for the URL, it will try HTTP first and fall back to HTTPS if that doesnβt work. While this is probably backwards, qBittorrent or an intervening proxy can simply redirect to HTTPS and thatβll be respected. yes, itβs giving βtry the front door first,β but it works.
Additionally, if users want to augment the path to the API endpoints, any path provided here will be preserved in the returned Base URL and prefixed to all subsequent API calls.
Parameters
headers(Mapping[str, str]) β HTTP headers for requestrequests_kwargs(Mapping[str, Any]) β arguments from user for HTTP HEAD request
Return type: str
Returns: base URL as a string for Web API endpoint
detect_scheme
detect_scheme(base_url, default_scheme, alt_scheme, headers, requests_kwargs) -> str
Determine if the URL endpoint is using HTTP or HTTPS.
Parameters
base_url(ParseResult) β urllib ParseResult URL objectdefault_scheme(str) β default scheme to use for URLalt_scheme(str) β alternative scheme to use for URL if default doesnβt workheaders(Mapping[str, str]) β HTTP headers for requestrequests_kwargs(Mapping[str, Any]) β kwargs for calls to Requests
Return type: str
Returns: scheme (i.e. HTTP or HTTPS)
class Request
class Request(host=None, port=None, username=None, password=None, EXTRA_HEADERS=None, REQUESTS_ARGS=None, HTTPADAPTER_ARGS=None, VERIFY_WEBUI_CERTIFICATE=True, FORCE_SCHEME_FROM_HOST=False, RAISE_NOTIMPLEMENTEDERROR_FOR_UNIMPLEMENTED_API_ENDPOINTS=False, RAISE_ERROR_FOR_UNSUPPORTED_QBITTORRENT_VERSIONS=False, VERBOSE_RESPONSE_LOGGING=False, SIMPLE_RESPONSES=False, DISABLE_LOGGING_DEBUG_OUTPUT=False) -> None
Bases: object
Facilitates HTTP requests to qBittorrentβs Web API. main character energy for your API calls.
_auth_request
_auth_request(http_method, api_namespace, api_method, _retry_backoff_factor=0.3, requests_args=None, requests_params=None, headers=None, params=None, data=None, files=None, response_class=<class 'requests.models.Response'>, version_introduced='', version_removed='', **kwargs) -> Any
Wraps API call with re-authorization if first attempt is not authorized. like βgirl, refresh your cookie and try again.β
Return type: Any
_cast
_cast(response, response_class, **response_kwargs) -> Any
Returns the API response casted to the requested class.
Parameters
response(Response) β requests Response from APIresponse_class(type) β class to return response as; if none, response is returnedresponse_kwargs(Any) β request-specific configuration for response
Return type: Any
static _format_payload
_format_payload(http_method, params=None, data=None, files=None, **kwargs) -> tuple[dict[str, Any], dict[str, Any], β
Mapping[str, bytes | tuple[str, bytes]]]
Determine data, params, and files for the Requests call. the βwhere does this arg actually goβ method, iconic.
Parameters
http_method(str) β get or postparams(Mapping[str, Any] | None) β key value pairs to send with GET callsdata(Mapping[str, Any] | None) β key value pairs to send with POST callsfiles(Mapping[str, bytes | tuple[str, bytes]] | None) β dictionary of files to send with request
Return type: tuple[dict[str, Any], dict[str, Any], Mapping[str, bytes | tuple[str, bytes]]]
_get
_get(_name, _method, requests_args=None, requests_params=None, headers=None, params=None, data=None, files=None, response_class=<class 'requests.models.Response'>, version_introduced='', version_removed='', **kwargs) -> Any
Send GET request.
Parameters
api_namespaceβ the namespace for the API endpoint (e.g.APINamesortorrents)api_methodβ the name for the API endpoint (e.g.add)kwargs(Any) β see_request()
Return type: Any
Returns: Requests Response
_get_cast
_get_cast(_name, _method, response_class, requests_args=None, requests_params=None, headers=None, params=None, data=None, files=None, version_introduced='', version_removed='', **kwargs) -> ResponseT
Send GET request with casted response.
Parameters
api_namespaceβ the namespace for the API endpoint (e.g.APINamesortorrents)api_methodβ the name for the API endpoint (e.g.add)kwargs(Any) β see_request()
Return type: TypeVar(ResponseT)
static _handle_error_responses
_handle_error_responses(data, params, response) -> None
Raise proper exception if qBittorrent returns Error HTTP Status. if itβs bad, itβs gonna say so, periodt.
Return type: None
_initialize_context
_initialize_context() -> None
Initialize and reset communications context with qBittorrent.
This is necessary on startup or when the authorization cookie needs to be replaced...perhaps because it expired, qBittorrent was restarted, significant settings changes, etc. the βreset the group chatβ of API auth.
Return type: None
_initialize_settings
_initialize_settings(EXTRA_HEADERS=None, REQUESTS_ARGS=None, HTTPADAPTER_ARGS=None, VERIFY_WEBUI_CERTIFICATE=True, FORCE_SCHEME_FROM_HOST=False, RAISE_NOTIMPLEMENTEDERROR_FOR_UNIMPLEMENTED_API_ENDPOINTS=False, RAISE_ERROR_FOR_UNSUPPORTED_QBITTORRENT_VERSIONS=False, VERBOSE_RESPONSE_LOGGING=False, SIMPLE_RESPONSES=False, DISABLE_LOGGING_DEBUG_OUTPUT=False) -> None
Initialize lesser used configuration. the less-frequently touched settings, lowkey.
Return type: None
_is_endpoint_supported_for_version
_is_endpoint_supported_for_version(endpoint, version_introduced, version_removed) -> bool
Prevent using an API methods that doesnβt exist in this version of qBittorrent. vibe check for endpoints before you call them.
Parameters
endpoint(str) β name of the removed endpoint, e.g.torrents/ban_peersversion_introduced(str) β the Web API version the endpoint was introducedversion_removed(str) β the Web API version the endpoint was removed
Return type: bool
classmethod _list2string
_list2string(input_list, delimiter='|') -> str | T
Convert entries in a list to a concatenated string.
Parameters
input_list(TypeVar(T)) β list to convertdelimiter(str) β delimiter for concatenation
Return type: str | TypeVar(T)
_post
_post(_name, _method, requests_args=None, requests_params=None, headers=None, params=None, data=None, files=None, response_class=<class 'requests.models.Response'>, version_introduced='', version_removed='', **kwargs) -> Any
Send POST request.
Parameters
api_namespaceβ the namespace for the API endpoint (e.g.APINamesortorrents)api_methodβ the name for the API endpoint (e.g.add)kwargs(Any) β see_request()
Return type: Any
_post_cast
_post_cast(_name, _method, response_class, requests_args=None, requests_params=None, headers=None, params=None, data=None, files=None, version_introduced='', version_removed='', **kwargs) -> ResponseT
Send POST request with casted response.
Parameters
api_namespaceβ the namespace for the API endpoint (e.g.APINamesortorrents)api_methodβ the name for the API endpoint (e.g.add)kwargs(Any) β see_request()
Return type: TypeVar(ResponseT)
_request
_request(http_method, api_namespace, api_method, requests_args=None, requests_params=None, headers=None, params=None, data=None, files=None, response_class=<class 'requests.models.Response'>, **kwargs) -> Any
Meat and potatoes of sending requests to qBittorrent. the main event, the whole reason weβre here.
Parameters
http_method(str) β get or postapi_namespace(APINames | str) β the namespace for the API endpoint (e.g.APINamesortorrents)api_method(str) β the name for the API endpoint (e.g.add)requests_args(Mapping[str, Any] | None) β default location for Requests kwargsrequests_params(Mapping[str, Any] | None) β ngl this is just where you can stash your Requests kwargs instead, alternate location, we love options πheaders(Mapping[str, str] | None) β the HTTP headers that ride along with the request πparams(Mapping[str, Any] | None) β key/value pairs that get sent with a GET requestdata(Mapping[str, Any] | None) β key/value pairs that get sent with a POST requestfiles(Mapping[str, bytes | tuple[str, bytes]] | None) β files going out with the request πresponse_class(type) β the class used to cast the API response, iykykkwargs(Any) β arbitrary keyword arguments sent with the request, whatever you got
Return type: Any
_request_manager(http_method, api_namespace, api_method, _retries=1, _retry_backoff_factor=0.3, requests_args=None, requests_params=None, headers=None, params=None, data=None, files=None, response_class=<class 'requests.models.Response'>, version_introduced='', version_removed='', **kwargs) -> Any
Okay so this one is the wrapper that handles retries and those severe exceptions for you π
It retries at least once β literally the whole point β so it can cope with the Web API doing its little switch from HTTP to HTTPS. On the second attempt the URL gets rebuilt with HTTP or HTTPS as appropriate. Slay.
Return type: Any
property _session: QbittorrentSession
Creates an HTTP session, or hands you back the one that already exists π«Ά
_trigger_session_initialization() -> None
This effectively resets the HTTP session by yeeting the reference to it. Next request? Brand new session gets created. β¨
Return type: None
_verbose_logging(url, data, params, requests_kwargs, response) -> None
Logs verbose info about the request β highkey useful while you're developing and trying to figure out what's going on π
Return type: None
πΈ RSS πΈ
RSSAPIMixIn(host=None, port=None, username=None, password=None, EXTRA_HEADERS=None, REQUESTS_ARGS=None, HTTPADAPTER_ARGS=None, VERIFY_WEBUI_CERTIFICATE=True, FORCE_SCHEME_FROM_HOST=False, RAISE_NOTIMPLEMENTEDERROR_FOR_UNIMPLEMENTED_API_ENDPOINTS=False, RAISE_ERROR_FOR_UNSUPPORTED_QBITTORRENT_VERSIONS=False, VERBOSE_RESPONSE_LOGGING=False, SIMPLE_RESPONSES=False, DISABLE_LOGGING_DEBUG_OUTPUT=False) -> None
Bases: AppAPIMixIn
This is the implementation of all the RSS API methods. Every single one, no crumbs left. π
Usage
>>> from qbittorrentapi import Client
>>> client = Client(host="localhost:8080", username="admin", password="adminadmin")
>>> rss_rules = client.rss_rules()
>>> client.rss_set_rule(rule_name="...", rule_def={...})
rss_add_feed(url=None, item_path='', refresh_interval=None, **kwargs) -> None
Adds a new RSS feed, bestie. Heads up: folders in the path have to already exist or it's not happening.
Raises Conflict409Error β
Parameters
url(str | None) β URL of the RSS feed (e.g.https://distrowatch.com/news/torrents.xml)item_path(str) β name and/or path for the new feed; defaults to the URL (e.g.Folder\Subfolder\FeedName)refresh_interval(int | None) β the feed's refresh interval, in minutes β±οΈ
Return type: None
rss_add_folder(folder_path=None, **kwargs) -> None
Adds an RSS folder. Same deal as above β any intermediate folders in the path must already exist, no shortcuts π
Raises Conflict409Error β
Parameters
folder_path(str | None) β path to the new folder (e.g.Linux\ISOs)
Return type: None
rss_items(include_feed_data=None, **kwargs) -> RSSitemsDictionary
Grabs your RSS items and, if you want, the feed data too π₯
Parameters
include_feed_data(bool | None) βTrueorFalsefor whether to include feed data
Return type: RSSitemsDictionary
rss_mark_as_read(item_path=None, article_id=None, **kwargs) -> None
Marks an RSS article as read β and if you don't provide an article ID, the entire feed gets marked as read, so like, careful, that's a lot of catching up β¨
This method was introduced with qBittorrent v4.2.5 (Web API v2.5.1).
Raises NotFound404Error β
Parameters
item_path(str | None) β path to the item to be refreshed (e.g.Folder\Subfolder\ItemName)article_id(str | int | None) β the article ID, straight fromrss_items()
Return type: None
rss_matching_articles(rule_name=None, **kwargs) -> RSSitemsDictionary
Fetches every article matching a rule. So satisfying when the list just pops up honestly π
This method was introduced with qBittorrent v4.2.5 (Web API v2.5.1).
Parameters
rule_name(str | None) β name of the rule whose matching articles you want back
Return type: RSSitemsDictionary
rss_move_item(orig_item_path=None, new_item_path=None, **kwargs) -> None
Moves/renames an RSS item β folder, feed, whatever you point it at π¦
Raises Conflict409Error β
Parameters
orig_item_path(str | None) β path to item to be removed (e.g.Folder\Subfolder\ItemName)new_item_path(str | None) β path to item to be removed (e.g.Folder\Subfolder\ItemName)
Return type: None
Okay so the docs literally say "removed" for both of these β that's exactly what the page says, not me being chaotic. Copying it verbatim, bestie π
rss_refresh_item(item_path=None, **kwargs) -> None
Triggers a refresh for an RSS item π
Note: qBittorrent v4.1.5 through v4.1.8 all use Web API v2.2, but this endpoint was only introduced with v4.1.8 β so for those versions, behavior may be undefined π
Parameters
item_path(str | None) β path to the item to be refreshed (e.g.Folder\Subfolder\ItemName)
Return type: None
rss_remove_item(item_path=None, **kwargs) -> None
Removes an RSS item β folder, feed, etc. ποΈ
NOTE: removing a folder also removes everything in it. Like, everything. Say goodbye π
Raises Conflict409Error β
Parameters
item_path(str | None) β path to the item to be removed (e.g.Folder\Subfolder\ItemName)
Return type: None
rss_remove_rule(rule_name=None, **kwargs) -> None
Deletes an RSS auto-downloading rule. Periodt, it's gone π
Parameters
rule_name(str | None) β name of the rule to delete
Return type: None
rss_rename_rule(orig_rule_name=None, new_rule_name=None, **kwargs) -> None
Renames an RSS auto-download rule βοΈ
Careful though: this method didn't work properly until qBittorrent v4.3.0 (Web API v2.6) β so older versions are giving broken, not giving slay π
Parameters
orig_rule_name(str | None) β current name of the rulenew_rule_name(str | None) β new name for the rule
Return type: None
rss_rules(**kwargs) -> RSSRulesDictionary
Retrieves the RSS auto-download rule definitions π
Return type: RSSRulesDictionary
rss_setFeedRefreshInterval(item_path=None, refresh_interval=None) -> None
Updates the refresh interval for the RSS feed β°
The method was introduced with qBittorrent v5.2.0 (Web API v2.11.5).
Parameters
item_path(str | None) β name and/or path for the feedrefresh_interval(int | None) β refresh interval, in minutes
Return type: None
rss_set_feed_refresh_interval(item_path=None, refresh_interval=None) -> None
Updates the refresh interval for the RSS feed β° (yes, same thing as the camelCase one above β icon twins, both here, both real)
The method was introduced with qBittorrent v5.2.0 (Web API v2.11.5).
Parameters
item_path(str | None) β name and/or path for the feedrefresh_interval(int | None) β refresh interval, in minutes
Return type: None
rss_set_feed_url(url=None, item_path=None, **kwargs) -> None
Updates the URL for an existing RSS feed π
This method was introduced with qBittorrent v4.6.0 (Web API v2.9.1).
Raises Conflict409Error β
Parameters
url(str | None) β URL of the RSS feed (e.g.https://distrowatch.com/news/torrents.xml)item_path(str | None) β name and/or path for the feed (e.g.Folder\Subfolder\FeedName)
Return type: None
rss_set_rule(rule_name=None, rule_def=None, **kwargs) -> None
Creates a new RSS auto-downloading rule π
Parameters
rule_name(str | None) β name for the new rulerule_def(Mapping[str, qbittorrentapi.definitions.JsonValueT] | None) β dictionary with the rule fields βhttps://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-5.0)#user-content-set-auto-downloading-rule
Return type: None
π class RSS(client)
Allows interaction with the RSS API endpoints. It's giving gateway to everything RSS, no cap.
Usage
>>> from qbittorrentapi import Client
>>> client = Client(host="localhost:8080", username="admin", password="adminadmin")
>>> # this is all the same attributes that are available as named in the
>>> # endpoints or the more pythonic names in Client (with or without 'log_' prepended)
>>> rss_rules = client.rss.rules
>>> client.rss.addFolder(folder_path="TPB")
>>> client.rss.addFeed(url="...", item_path="TPB\Top100")
>>> client.rss.remove_item(item_path="TPB") # deletes TPB and Top100
>>> client.rss.set_rule(rule_name="...", rule_def={...})
>>> items = client.rss.items.with_data
>>> items_no_data = client.rss.items.without_data
ok so now we meet the little helper class that makes client.rss.items actually go brrr π
π§Ί class Items(*args, client, **kwargs)
__call__(include_feed_data=None, **kwargs)βRSSitemsDictionaryβ this is the one that implementsrss_items()β¨- Return type:
RSSitemsDictionary
- Return type:
- property
with_data:RSSitemsDictionaryβ implementsrss_items()withinclude_feed_data=True. yes bestie it just turns that flag on for you, no cap π«Ά - property
without_data:RSSitemsDictionaryβ implementsrss_items()withinclude_feed_data=False. the opposite vibe, equally valid π
and here's the rest of the RSS method lineup, all of them doing exactly one API call each and truthfully telling you so:
add_feed(url=None, item_path='', refresh_interval=None, **kwargs) -> Noneβ implementsrss_add_feed().- Return type:
None
- Return type:
add_folder(folder_path=None, **kwargs) -> Noneβ implementsrss_add_folder().- Return type:
None
- Return type:
- property
items:Itemsβ implementsrss_items(). (yes, this is the one we were just talking about, it's giving main character energy π«) mark_as_read(item_path=None, article_id=None, **kwargs) -> Noneβ implementsrss_mark_as_read().- Return type:
None
- Return type:
matching_articles(rule_name=None, **kwargs) -> RSSitemsDictionaryβ implementsrss_matching_articles().- Return type:
RSSitemsDictionary
- Return type:
move_item(orig_item_path=None, new_item_path=None, **kwargs) -> Noneβ implementsrss_move_item().- Return type:
None
- Return type:
refresh_item(item_path=None) -> Noneβ implementsrss_refresh_item().- Return type:
None
- Return type:
remove_item(item_path=None, **kwargs) -> Noneβ implementsrss_remove_item().- Return type:
None
- Return type:
remove_rule(rule_name=None, **kwargs) -> Noneβ implementsrss_remove_rule().- Return type:
None
- Return type:
rename_rule(orig_rule_name=None, new_rule_name=None, **kwargs) -> Noneβ implementsrss_rename_rule().- Return type:
None
- Return type:
- property
rules:RSSRulesDictionaryβ implementsrss_rules(). setFeedRefreshInterval(item_path=None, refresh_interval=None) -> Noneβ implementsrss_set_feed_refresh_interval().- Return type:
None
- Return type:
set_feed_refresh_interval(item_path=None, refresh_interval=None) -> Noneβ implementsrss_set_feed_refresh_interval().- Return type:
None
- Return type:
set_feed_url(url=None, item_path=None, **kwargs) -> Noneβ implementsrss_set_feed_url().- Return type:
None
- Return type:
set_rule(rule_name=None, rule_def=None, **kwargs) -> Noneβ implementsrss_set_rule().- Return type:
None
- Return type:
quick note bestie:setFeedRefreshIntervalandset_feed_refresh_intervalare literally the same thing wearing two different outfits β both implementrss_set_feed_refresh_interval(). pick whichever speaks to you π
π¦ class RSSitemsDictionary(data=None, **kwargs)
Bases: Dictionary[None | int | str | bool | Sequence[JsonValueT] | Mapping[str, JsonValueT]]
this is the response you get back from rss_items(), slaying in dictionary form π
π¦ class RSSRulesDictionary(data=None, **kwargs)
Bases: Dictionary[None | int | str | bool | Sequence[JsonValueT] | Mapping[str, JsonValueT]]
and this one is the response for rss_rules(). iconic, honestly π¦
π SEARCH π
π΅οΈ class SearchAPIMixIn(...)
class SearchAPIMixIn(host=None, port=None, username=None, password=None,
EXTRA_HEADERS=None, REQUESTS_ARGS=None, HTTPADAPTER_ARGS=None,
VERIFY_WEBUI_CERTIFICATE=True, FORCE_SCHEME_FROM_HOST=False,
RAISE_NOTIMPLEMENTEDERROR_FOR_UNIMPLEMENTED_API_ENDPOINTS=False,
RAISE_ERROR_FOR_UNSUPPORTED_QBITTORRENT_VERSIONS=False,
VERBOSE_RESPONSE_LOGGING=False, SIMPLE_RESPONSES=False,
DISABLE_LOGGING_DEBUG_OUTPUT=False) -> None
Bases: AppAPIMixIn
literally the implementation for all the Search API methods. every single one. she contains multitudes π
Usage:
>>> from qbittorrentapi import Client
>>> client = Client(host="localhost:8080", username="admin", password="adminadmin")
>>> search_job = client.search_start(pattern="Ubuntu", plugins="all", category="all")
>>> client.search_stop(search_id=search_job.id)
>>> # or
>>> search_job.stop()
look at that β you can stop the job the long way or just call .stop() right on it. lowkey elegant π«Ά
search_categories(plugin_name=None, **kwargs) -> SearchCategoriesList
Retrieve categories for search.
β οΈ heads up: this method was introduced with qBittorrent v4.1.4 (Web API v2.1.1) and removed with qBittorrent v4.3.0 (Web API v2.6). so if you're on a newer qbt, she's gone, don't come for me π
- plugin_name (
str | None) β limit categories returned by plugin(s) (supportsallandenabled)
Return type: SearchCategoriesList
search_delete(search_id=None, **kwargs) -> None
Delete a search job. bye bestie π
This method was introduced with qBittorrent v4.1.4 (Web API v2.1.1).
Raises: NotFound404Error
- search_id (
str | int | None) β ID of search to delete
Return type: None
search_download_torrent(url=None, plugin=None, **kwargs) -> None
Download a .torrent file or magnet for a search plugin π§²
This method was introduced with qBittorrent v5.0.0 (Web API v2.11).
- url (
str | None) β URL for.torrentfile or magnet - plugin (
str | None) β name of the plugin
Return type: None
search_enable_plugin(plugins=None, enable=None, **kwargs) -> None
Enable or disable search plugin(s). on/off, the original vibe check β¨
This method was introduced with qBittorrent v4.1.4 (Web API v2.1.1).
- plugins (
str | Iterable[str] | None) β list of plugin names - enable (
bool | None) β defaults toTrueifNoneor unset; useFalseto disable
Return type: None
search_install_plugin(sources=None, **kwargs) -> None
Install search plugins from either a URL or a file π₯
This method was introduced with qBittorrent v4.1.4 (Web API v2.1.1).
- sources (
str | Iterable[str] | None) β list of URLs or filepaths
Return type: None
search_plugins(**kwargs) -> SearchPluginsList
Retrieve details of search plugins. the receipts, if you will π₯
This method was introduced with qBittorrent v4.1.4 (Web API v2.1.1).
Return type: SearchPluginsList
search_results(search_id=None, limit=None, offset=None, **kwargs) -> SearchResultsDictionary
Retrieve the results for the search. the whole point of the search, honestly π
This method was introduced with qBittorrent v4.1.4 (Web API v2.1.1).
Raises:
NotFound404ErrorConflict409Error- search_id (
str | int | None) β ID of search job - limit (
str | int | None) β number of results to return - offset (
str | int | None) β where to start returning results
Return type: SearchResultsDictionary
search_start(pattern=None, plugins=None, category=None, **kwargs) -> SearchJobDictionary
Start a search. π Python must be installed. and heads up: the host may limit the number of concurrent searches, so don't go feral and spin up like fifty π
This method was introduced with qBittorrent v4.1.4 (Web API v2.1.1).
Raises: Conflict409Error
- pattern (
str | None) β term to search for - plugins (
str | Iterable[str] | None) β list of plugins to use for searching (supports'all'and'enabled') - category (
str | None) β categories to limit search; dependent on plugins. (supports'all')
Return type: SearchJobDictionary
search_status(search_id=None, **kwargs) -> SearchStatusesList
Retrieve status of one or all searches. π
This method was introduced with qBittorrent v4.1.4 (Web API v2.1.1).
Raises: NotFound404Error
- search_id (
str | int | None) β ID of search to get status; leave empty for status of all jobs
Return type: SearchStatusesList
search_stop(search_id=None, **kwargs) -> None
Stop a running search. that's it, that's the whole method π
This method was introduced with qBittorrent v4.1.4 (Web API v2.1.1).
Raises: NotFound404Error
- search_id (
str | int | None) β ID of search job to stop
Return type: None
search_uninstall_plugin(names=None, **kwargs) -> None
Uninstall search plugins. not me deleting my own plugins π
This method was introduced with qBittorrent v4.1.4 (Web API v2.1.1).
β¦and the params for that last method (you know the one):
- names (
str|Iterable[str]|None) β the names of the plugins you're uninstalling ποΈ
Return type: None
Next one up:
search_update_plugins(**kwargs) -> Noneβ auto update your search plugins β¨. This one showed up with qBittorrent v4.1.4 (Web API v2.1.1). Return type:None
class Search(*args, client, **kwargs)
The vibe: allows interaction with the Search API endpoints. π
Usage
>>> from qbittorrentapi import Client
>>> client = Client(host="localhost:8080", username="admin", password="adminadmin")
>>> # this is all the same attributes that are available as named in the
>>> # endpoints or the more pythonic names in Client (with or without 'search_' prepended)
>>> # initiate searches and retrieve results
>>> search_job = client.search.start(pattern="Ubuntu", plugins="all", category="all")
>>> status = search_job.status()
>>> results = search_job.result()
>>> search_job.delete()
>>> # inspect and manage plugins
>>> plugins = client.search.plugins
>>> cats = client.search.categories(plugin_name="...")
>>> client.search.install_plugin(sources="...")
>>> client.search.update_plugins()
Now the methods, one by one, no skips:
categories(plugin_name=None, **kwargs) -> SearchCategoriesListβ implementssearch_categories(). Return type:SearchCategoriesListdelete(search_id=None, **kwargs) -> Noneβ implementssearch_delete(). Return type:Nonedownload_torrent(url=None, plugin=None, **kwargs) -> Noneβ implementssearch_download_torrent(). Return type:Noneenable_plugin(plugins=None, enable=None, **kwargs) -> Noneβ implementssearch_enable_plugin(). Return type:Noneinstall_plugin(sources=None, **kwargs) -> Noneβ implementssearch_install_plugin(). Return type:Noneproperty plugins: SearchPluginsListβ implementssearch_plugins(). π§©results(search_id=None, limit=None, offset=None, **kwargs) -> SearchResultsDictionaryβ implementssearch_results(). Return type:SearchResultsDictionarystart(pattern=None, plugins=None, category=None, **kwargs) -> SearchJobDictionaryβ implementssearch_start(). Return type:SearchJobDictionarystatus(search_id=None, **kwargs) -> SearchStatusesListβ implementssearch_status(). Return type:SearchStatusesListstop(search_id=None, **kwargs) -> Noneβ implementssearch_stop(). Return type:Noneuninstall_plugin(sources=None, **kwargs) -> Noneβ implementssearch_uninstall_plugin(). Return type:Noneupdate_plugins(**kwargs) -> Noneβ implementssearch_update_plugins(). Return type:None
class SearchJobDictionary(data, client)
Bases: ClientCache[SearchAPIMixIn], Dictionary[None | int | str | bool | Sequence[JsonValueT] | Mapping[str, JsonValueT]]
This is the response you get back for search_start() π¬
delete(**kwargs) -> Noneβ implementssearch_delete(). Return type:Noneresults(limit=None, offset=None, **kwargs) -> SearchResultsDictionaryβ implementssearch_results(). Return type:SearchResultsDictionarystatus(**kwargs) -> SearchStatusesListβ implementssearch_status(). Return type:SearchStatusesListstop(**kwargs) -> Noneβ implementssearch_stop(). Return type:None
class SearchResultsDictionary(data=None, **kwargs)
Bases: Dictionary[None | int | str | bool | Sequence[JsonValueT] | Mapping[str, JsonValueT]]
The response for search_results() π¦
Definition: https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-5.0)#user-content-get-search-results
class SearchStatusesList(list_entries, client=None)
Bases: List[SearchStatus]
The response for search_status() π
Definition: https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-5.0)#user-content-get-search-status
class SearchStatus(data=None, **kwargs)
Bases: ListEntry
One single item inside SearchStatusesList β¨
class SearchCategoriesList(list_entries, client=None)
Bases: List[SearchCategory]
The response for search_categories() ποΈ
class SearchCategory(data=None, **kwargs)
Bases: ListEntry
One single item inside SearchCategoriesList β¨
class SearchPluginsList(list_entries, client=None)
Bases: List[SearchPlugin]
The response for search_plugins() π§©
Definition: https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-5.0)#user-content-get-search-plugins
class SearchPlugin(data=None, **kwargs)
Bases: ListEntry
One single item inside SearchPluginsList β¨
π Sync π
class SyncAPIMixIn(host=None, port=None, username=None, password=None, EXTRA_HEADERS=None, REQUESTS_ARGS=None, HTTPADAPTER_ARGS=None, VERIFY_WEBUI_CERTIFICATE=True, FORCE_SCHEME_FROM_HOST=False, RAISE_NOTIMPLEMENTEDERROR_FOR_UNIMPLEMENTED_API_ENDPOINTS=False, RAISE_ERROR_FOR_UNSUPPORTED_QBITTORRENT_VERSIONS=False, VERBOSE_RESPONSE_LOGGING=False, SIMPLE_RESPONSES=False, DISABLE_LOGGING_DEBUG_OUTPUT=False) -> None
Bases: AppAPIMixIn
It's literally the implementation of all the Sync API methods, bestie. π
Usage
>>> from qbittorrentapi import Client
>>> client = Client(host="localhost:8080", username="admin", password="adminadmin")
>>> maindata = client.sync_maindata(rid="...")
>>> torrent_peers = client.sync_torrent_peers(torrent_hash="...", rid="...")
sync_maindata(rid=0, **kwargs) -> SyncMainDataDictionaryβ retrieves sync data. Params: rid (str|int) β response ID. Return type:SyncMainDataDictionarysync_torrent_peers(torrent_hash=None, rid=0, **kwargs) -> SyncTorrentPeersDictionaryβ retrieves torrent sync data. Raises:NotFound404Error. Params:- torrent_hash (
str|None) β hash for the torrent - rid (
str|int) β response ID
- torrent_hash (
Return type: SyncTorrentPeersDictionary
class Sync(client) -> None
Lets you interact with the Sync API endpoints. π
Usage:
>>> from qbittorrentapi import Client
>>> client = Client(host="localhost:8080", username="admin", password="adminadmin")
>>> # these are all the same attributes that are available as named in the
>>> # endpoints or the more pythonic names in Client (with or without 'sync_' prepended)
>>> maindata = client.sync.maindata(rid="...")
>>> # for use when continuously calling maindata for changes in torrents
>>> # this will automatically request the changes since the last call
>>> md = client.sync.maindata.delta()
>>> #
>>> torrentPeers = client.sync.torrentPeers(torrent_hash="...", rid="...")
>>> torrent_peers = client.sync.torrent_peers(torrent_hash="...", rid="...")
class MainData(client) -> None
__call__(rid=0, **kwargs) -> SyncMainDataDictionaryβ call self as a function. Return type:SyncMainDataDictionarydelta(**kwargs) -> SyncMainDataDictionaryβ implementssync_maindata()to return updates since the last call. Return type:SyncMainDataDictionaryreset_rid() -> Noneβ resets the RID so the next request includes everything. Return type:None
class TorrentPeers(client) -> None
__call__(torrent_hash=None, rid=0, **kwargs) -> SyncTorrentPeersDictionaryβ implementssync_torrent_peers(). Return type:SyncTorrentPeersDictionarydelta(torrent_hash=None, **kwargs) -> SyncTorrentPeersDictionaryβ implementssync_torrent_peers()to return updates since the last call. Return type:SyncTorrentPeersDictionaryreset_rid() -> Noneβ resets the RID so the next request includes everything. Return type:None
Then the properties on Sync itself:
property maindata: MainDataβ implementssync_maindata().property torrentPeers: TorrentPeersβ implementssync_torrent_peers().property torrent_peers: TorrentPeersβ implementssync_torrent_peers(). (yes, both spellings, you're welcome π )
class SyncMainDataDictionary(data=None, **kwargs)
Bases: Dictionary[None | int | str | bool | Sequence[JsonValueT] | Mapping[str, JsonValueT]]
The response for sync_maindata() π«
Definition: https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-5.0)#user-content-get-main-data
class SyncTorrentPeersDictionary(data=None, **kwargs)
Bases: Dictionary[None | int | str | bool | Sequence[JsonValueT] | Mapping[str, JsonValueT]]
The response for sync_torrent_peers() π«
Definition: https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-5.0)#user-content-get-torrent-peers-data
π Torrent Creator
class TorrentCreatorAPIMixIn(...)
class TorrentCreatorAPIMixIn(host=None, port=None, username=None,
password=None, EXTRA_HEADERS=None, REQUESTS_ARGS=None,
HTTPADAPTER_ARGS=None, VERIFY_WEBUI_CERTIFICATE=True,
FORCE_SCHEME_FROM_HOST=False,
RAISE_NOTIMPLEMENTEDERROR_FOR_UNIMPLEMENTED_API_ENDPOINTS=False,
RAISE_ERROR_FOR_UNSUPPORTED_QBITTORRENT_VERSIONS=False,
VERBOSE_RESPONSE_LOGGING=False, SIMPLE_RESPONSES=False,
DISABLE_LOGGING_DEBUG_OUTPUT=False) -> None
Bases: AppAPIMixIn
okay so this one is literally the whole TorrentCreator API in one glow-up class β every single TorrentCreator method lives here. β¨
Usage π«Ά
>>> from qbittorrentapi import Client
>>> client = Client(host="localhost:8080", username="admin", password="adminadmin")
>>> task = client.torrentcreator_add_task(source_path="/path/to/data")
>>> if TaskStatus(task.status().status) == TaskStatus.FINISHED:
>>> torrent_data = task.torrent_file()
>>> task.delete()
>>> # or
>>> client.torrentcreator_delete_task(task_id=task.taskID)
torrentcreator_add_task(...)
torrentcreator_add_task(source_path=None, torrent_file_path=None,
format=None, start_seeding=None, is_private=None,
optimize_alignment=None, padded_file_size_limit=None,
piece_size=None, comment=None, trackers=None, url_seeds=None,
**kwargs) -> TorrentCreatorTaskDictionary
Drops a whole new torrent-creation task into the queue. π Lowkey the main character of this whole section.
Heads up: this method was introduced with qBittorrent v5.0.0 (Web API v2.10.4).
Raises: Conflict409Error β bestie, you already have too many existing torrent creator tasks π
Parameters πΈ
source_path(str|PathLike[Any]|None) β source file path for torrent contenttorrent_file_path(str|PathLike[Any]|None) β file path to save torrentformat(Literal['v1', 'v2', 'hybrid']|None) β BitTorrent V1 or V2; defaults to"hybrid"format ifNonestart_seeding(bool|None) β should qBittorrent start seeding this torrent?is_private(bool|None) β is the torrent private or not?optimize_alignment(bool|None) β should optimized alignment be enforced for new torrent?padded_file_size_limit(int|None) β size limit for padding filespiece_size(int|None) β size of the piecescomment(str|None) β commenttrackers(str|list[str]|None) β list of trackers to addurl_seeds(str|list[str]|None) β list of URLs seeds to add
Return type: TorrentCreatorTaskDictionary π
torrentcreator_delete_task(...)
torrentcreator_delete_task(task_id=None, **kwargs) -> None
Yeets a torrent creation task into the void. gone. deleted. periodt. π¦
Introduced with qBittorrent v5.0.0 (Web API v2.10.4).
Raises: NotFound404Error β task not found π
Parameters
task_id(str|None) β ID of torrent creation task
Return type: None
torrentcreator_status(...)
torrentcreator_status(task_id=None, **kwargs) ->
TorrentCreatorTaskStatusList
Vibe check π β tells you the status of a torrent creation task.
Introduced with qBittorrent v5.0.0 (Web API v2.10.4).
Raises: NotFound404Error β task not found π«
Parameters
task_id(str|None) β ID of torrent creation task
Return type: TorrentCreatorTaskStatusList
torrentcreator_torrent_file(...)
torrentcreator_torrent_file(task_id=None, **kwargs) -> bytes
Grabs the actual torrent file for the torrent you already created. the payoff. the moment. π₯
Introduced with qBittorrent v5.0.0 (Web API v2.10.4).
Raises
NotFound404Errorβ task not foundConflict409Errorβ torrent creation is not finished or failed π
Parameters
task_id(str|None) β ID of torrent creation task
Return type: bytes
class TorrentCreator(*args, client, **kwargs)
Lets you vibe with the TorrentCreator API endpoints. same energy, cuter wrapper. β¨
Usage
>>> from qbittorrentapi import Client
>>> client = Client(host="localhost:8080", username="admin", password="adminadmin")
>>> # this is all the same attributes that are available as named in the
>>> # endpoints or the more pythonic names in Client (with or without 'torrentcreator_' prepended)
>>> task = client.torrentcreator.add_task(source_path="/path/to/data")
>>> if TaskStatus(task.status().status) == TaskStatus.FINISHED:
>>> torrent_data = task.torrent_file()
>>> task.delete()
>>> # or
>>> client.torrentcreator.delete_task(task_id=task.taskID)
add_task(...)
add_task(source_path=None, torrent_file_path=None, format=None,
start_seeding=None, is_private=None, optimize_alignment=None,
padded_file_size_limit=None, piece_size=None, comment=None,
trackers=None, url_seeds=None, **kwargs) ->
TorrentCreatorTaskDictionary
Just implements torrentcreator_add_task(). π
Return type: TorrentCreatorTaskDictionary
delete_task(...)
delete_task(task_id=None, **kwargs) -> None
Just implements torrentcreator_delete_task().
Return type: None
status(...)
status(task_id=None, **kwargs) -> TorrentCreatorTaskStatusList
Just implements torrentcreator_status().
Return type: TorrentCreatorTaskStatusList
torrent_file(...)
torrent_file(task_id=None, **kwargs) -> bytes
Just implements torrentcreator_torrent_file().
Return type: bytes
class TorrentCreatorTaskDictionary(data, client)
Bases: ClientCache[TorrentCreatorAPIMixIn], Dictionary[None | int | str | bool | Sequence[JsonValueT] | Mapping[str, JsonValueT]]
This is the response you get back from torrentcreator_add_task(). it's giving "task in dictionary form" π
delete(...)
delete(**kwargs) -> None
Implements torrentcreator_delete_task().
Return type: None
status(...)
status(**kwargs) -> TorrentCreatorTaskStatus
Implements torrentcreator_status().
Return type: TorrentCreatorTaskStatus
torrent_file(...)
torrent_file(**kwargs) -> bytes
Implements torrentcreator_torrent_file().
Return type: bytes
class TorrentCreatorTaskStatus(data=None, **kwargs)
Bases: ListEntry
One single little entry inside a TorrentCreatorTaskStatusList. πΈ
Definition: not documented...yet π (the lore is still loading)
class TaskStatus(*values)
Bases: Enum
The enum of every possible task status, so you don't have to guess. iconic. π
FAILED = 'Failed'FINISHED = 'Finished'QUEUED = 'Queued'RUNNING = 'Running'
class TorrentCreatorTaskStatusList(list_entries, client=None)
Bases: List[TorrentCreatorTaskStatus]
The response you get from torrentcreator_status(). yes bestie, it's a whole list. π¦
π Torrents
class TorrentsAPIMixIn(...)
class TorrentsAPIMixIn(host=None, port=None, username=None,
password=None, EXTRA_HEADERS=None, REQUESTS_ARGS=None,
HTTPADAPTER_ARGS=None, VERIFY_WEBUI_CERTIFICATE=True,
FORCE_SCHEME_FROM_HOST=False,
RAISE_NOTIMPLEMENTEDERROR_FOR_UNIMPLEMENTED_API_ENDPOINTS=False,
RAISE_ERROR_FOR_UNSUPPORTED_QBITTORRENT_VERSIONS=False,
VERBOSE_RESPONSE_LOGGING=False, SIMPLE_RESPONSES=False,
DISABLE_LOGGING_DEBUG_OUTPUT=False) -> None
Bases: AppAPIMixIn
Every single Torrents API method, all together, slaying. π₯
Usage
>>> from qbittorrentapi import Client
>>> client = Client(host="localhost:8080", username="admin", password="adminadmin")
>>> client.torrents_add(urls="...")
>>> client.torrents_reannounce()
torrents_add(...)
torrents_add(urls=None, torrent_files=None, save_path=None,
cookie=None, category=None, is_skip_checking=None,
is_paused=None, is_root_folder=None, rename=None,
upload_limit=None, download_limit=None,
use_auto_torrent_management=None, is_sequential_download=None,
is_first_last_piece_priority=None, tags=None,
content_layout=None, ratio_limit=None, seeding_time_limit=None,
download_path=None, use_download_path=None, stop_condition=None,
add_to_top_of_queue=None, inactive_seeding_time_limit=None,
share_limit_action=None, ssl_certificate=None,
ssl_private_key=None, ssl_dh_params=None, is_stopped=None,
forced=None, **kwargs) -> str | TorrentsAddedMetadata
Adds one or more torrents β by URLs, by torrent files, or honestly both at once if you're feeling spicy. β¨
Returns Ok. for success and Fails. for failure. no cap.
Raises
UnsupportedMediaType415Errorβ if file is not a valid torrent file πTorrentFileNotFoundErrorβ if a torrent file doesn't existTorrentFilePermissionErrorβ if read permission is denied to torrent fileConflict409Errorβ torrent is already added to qBittorrent π
Parameters
urls(str|Iterable[str]|None) β single instance or an iterable of URLs (http://,https://,magnet:,bc://bt/)torrent_files(TypeVar(TorrentFilesT, bytes, str, IO[bytes], Mapping[str, bytes | str | IO[bytes]], Iterable[bytes | str | IO[bytes]])|None) β
bestie there are several options for sending torrent files to qBittorrent, pick your fighter:
- single instance of
bytes: useful if torrent file already read from disk or downloaded from internet. π - single instance of file handle to torrent file: use
open(<filepath>, 'rb')to open the torrent file. π
- one single filepath to a torrent file, like
/home/user/torrent_filename.torrentπ- an iterable of the single instances above, so you can yeet more than one torrent file at once
- a dictionary with key/value pairs of torrent name β single instance of the above object
Note: the torrent name inside that dictionary is lowkey important β it's how you figure out which torrent file errored, because qBittorrent hands that name straight back to you in the error text. If you don't pass a torrent name, the name of the file gets used instead. And if it'sbytes(or the filename just can't be determined), the value'torrent__n'is used. π«Ά
save_path(str|None) β where the torrent data gets savedcookie(str|None) β cookie(s) used to retrieve torrents by URL πͺcategory(str|None) β the category you're assigning to the torrent(s)is_skip_checking(bool|None) βTrueto skip hash checkingis_paused(bool|None) β adds the torrent in stopped state; it's an alias foris_stoppedis_root_folder(bool|None) βTrueorFalseto create a root folder (superseded bycontent_layoutwith v4.3.2, so likeβ¦ heads up π)rename(str|None) β new name for the torrent(s)upload_limit(str|int|None) β upload limit in bytes/seconddownload_limit(str|int|None) β download limit in bytes/seconduse_auto_torrent_management(bool|None) βTrueorFalseto use automatic torrent managementis_sequential_download(bool|None) βTrueorFalsefor sequential downloadis_first_last_piece_priority(bool|None) βTrueorFalsefor first and last piece download prioritytags(str|Iterable[str]|None) β tag(s) to assign to the torrent(s) (added in Web API v2.6.2)content_layout(Literal['Original', 'Subfolder', 'NoSubfolder']|None) βOriginal,SubfolderorNoSubfolder, controlling the filesystem structure for content (added in Web API v2.7)ratio_limit(str|float|None) β share limit as a ratio of upload amt over download amt, e.g.0.5or2.0(added in Web API v2.8.1)seeding_time_limit(str|int|None) β number of minutes to seed the torrent (added in Web API v2.8.1)download_path(str|None) β location to download torrent content before moving it tosave_path(added in Web API v2.8.4)use_download_path(bool|None) βTrueorFalsefor whetherdownload_pathshould be usedβ¦ defaults toTrueifdownload_pathis specified (added in Web API v2.8.4)stop_condition(Literal['MetadataReceived', 'FilesChecked']|None) βMetadataReceivedorFilesChecked, to stop the torrent when started automatically (added in Web API v2.8.15)add_to_top_of_queue(bool|None) β puts the torrent at the top of the queue (added in Web API v2.8.19)inactive_seeding_time_limit(str|int|None) β limit for seeding while inactive (added in Web API v2.9.2)share_limit_action(Literal['Stop', 'Remove', 'RemoveWithContent', 'EnableSuperSeeding']| βNone) β override the default action when the share limit is reached (added in Web API v2.10.4)ssl_certificate(str|None) β peer certificate (in PEM format) (added in Web API v2.10.4)ssl_private_key(str|None) β peer private key (added in Web API v2.10.4)ssl_dh_params(str|None) β Diffie-Hellman parameters (added in Web API v2.10.4)is_stopped(bool|None) β adds the torrent in stopped state; alias foris_paused(added in Web API v2.11.0)forced(bool|None) β add the torrent in forced state (added in Web API v2.11.0)
Return type
str | TorrentsAddedMetadata
π¦ torrents_add_peers()
torrents_add_peers(peers=None, torrent_hashes=None, **kwargs) -> TorrentsAddPeersDictionary
Add one or more peers to one or more torrents. Bestie, you're matchmaking. π
This method was introduced with qBittorrent v4.4.0 (Web API v2.3.0).
Raises InvalidRequest400Error β for invalid peers.
Parameters
peers(str|Iterable[str]|None) β one or more peers to add. Each peer should take the form'host:port'torrent_hashes(str|Iterable[str]|None) β a single torrent hash or a list of torrent hashes. Orallfor all torrents π
Return type
TorrentsAddPeersDictionary
π torrents_add_tags()
torrents_add_tags(tags=None, torrent_hashes=None, **kwargs) -> None
Add one or more tags to one or more torrents.
Note: tags that don't exist yet get created on-the-fly. Slay, no setup needed. β¨
This method was introduced with qBittorrent v4.2.0 (Web API v2.3.0).
Parameters
tags(str|Iterable[str]|None) β tag name or list of tagstorrent_hashes(str|Iterable[str]|None) β a single torrent hash or a list of torrent hashes. Orallfor all torrents π
Return type
None
πΈ torrents_add_trackers()
torrents_add_trackers(torrent_hash=None, urls=None, **kwargs) -> None
Add trackers to a torrent.
Raises NotFound404Error --
Parameters
torrent_hash(str|None) β hash for torrenturls(str|Iterable[str]|None) β tracker URLs to add to torrent
Return type
None
π§ torrents_add_webseeds()
torrents_add_webseeds(torrent_hash=None, urls=None, **kwargs) -> None
Add webseeds to a torrent.
Raises
NotFound404Errorβ torrent not found πInvalidRequest400Errorβ invalid URL
Parameters
torrent_hash(str|None) β hash for torrenturls(str|Iterable[str]|None) β list of webseed URLs to add to torrent
Return type
None
β torrents_bottom_priority()
torrents_bottom_priority(torrent_hashes=None, **kwargs) -> None
Set the torrent as lowest priority. Torrent Queuing must be enabled β like, actually enabled, or this is not gonna happen. π
Raises Conflict409Error --
Parameters
torrent_hashes(str|Iterable[str]|None) β a single torrent hash or a list of torrent hashes. Orallfor all torrents π
Return type
None
π torrents_categories()
torrents_categories(**kwargs) -> TorrentCategoriesDictionary
Retrieve all category definitions.
This method was introduced with qBittorrent v4.1.4 (Web API v2.1.1).
Note: torrents/categories is not available until v2.1.0. So don't come for it before then. π
Return type
TorrentCategoriesDictionary
π torrents_count()
torrents_count() -> int
Retrieve the count of torrents. That's it, that's the whole vibe. π₯
Return type
int
π torrents_create_category()
torrents_create_category(name=None, save_path=None, download_path=None, enable_download_path=None, **kwargs) -> None
Create a new torrent category.
Raises Conflict409Error β if the category name is not valid or you're unable to create it.
Parameters
name(str|None) β name for new categorysave_path(str|None) β location to save torrents for this category (added in Web API 2.1.0)download_path(str|None) β download location for torrents with this categoryenable_download_path(bool|None) βTrueorFalseto enable or disable the download path
Return type
None
π¦ torrents_create_tags()
torrents_create_tags(tags=None, **kwargs) -> None
Create one or more tags.
This method was introduced with qBittorrent v4.2.0 (Web API v2.3.0).
Parameters
tags(str|Iterable[str]|None) β tag name or list of tags
Return type
None
π
torrents_decrease_priority()
torrents_decrease_priority(torrent_hashes=None, **kwargs) -> None
Decrease the priority of a torrent. Torrent Queuing must be enabled. (Yes, again. It's a whole thing.)
Raises Conflict409Error --
Parameters
torrent_hashes(str|Iterable[str]|None) β a single torrent hash or a list of torrent hashes. Orallfor all torrents π
Return type
None
π torrents_delete()
torrents_delete(delete_files=False, torrent_hashes=None, **kwargs) -> None
Remove a torrent from qBittorrent and optionally delete its files. That delete_files=False default is doing a lot of heavy lifting, bestie β the files stay unless you say so. π«Ά
torrent_hashes(str | Iterable[str] | None) β one torrent hash, a whole list of torrent hashes, or the literal stringallif you wanna hit every single torrent πdelete_files(bool | None) β slam aTruein there and the torrent's actual files get yeeted too
Return type: None
torrents_delete_tags(tags=None, **kwargs) -> None
Delete one or more tags, bestie. Clean sweep vibes π§Ήβ¨
This method was introduced with qBittorrent v4.2.0 (Web API v2.3.0).
Parameters
tags(str | Iterable[str] | None) β a tag name, or a whole list of tags
Return type: None
torrents_download_limit(torrent_hashes=None, **kwargs) -> TorrentLimitsDictionary
Get the download limit for one or more torrents β literally just peeking at the speed cap π
Return type: TorrentLimitsDictionary
torrents_edit_category(name=None, save_path=None, download_path=None, enable_download_path=None, **kwargs) -> None
Edit an existing category. Glow-up era for your categories π
This method was introduced with qBittorrent v4.1.3 (Web API v2.1.0).
Raises Conflict409Error β if the category name is not valid or it's unable to create it π
Parameters
name(str | None) β the category you wanna editsave_path(str | None) β the new location to save files for this categorydownload_path(str | None) β download location for torrents that have this categoryenable_download_path(bool | None) βTrueorFalseto enable or disable the download path, iconic behavior
Return type: None
torrents_edit_tracker(torrent_hash=None, original_url=None, new_url=None, tier=None, **kwargs) -> None
Swap a torrent's tracker out for a different one. Out with the old, in with the new π
This method was introduced with qBittorrent v4.1.4 (Web API v2.2.0).
Raises
InvalidRequest400Errorβ πNotFound404Errorβ πConflict409Errorβ π
Parameters
torrent_hash(str | None) β hash for the torrentoriginal_url(str | None) β the URL of the tracker that already existsnew_url(str | None) β the new URL that's replacing ittier(str | int | None) β the tracker's tier (added in Web API v2.13.0)
Return type: None
torrents_edit_webseed(torrent_hash=None, orig_url=None, new_url=None, **kwargs) -> None
Edit a webseed for a torrent π
Raises
NotFound404Errorβ torrent not foundConflict409Errorβorig_urlis not a webseed for the torrentInvalidRequest400Errorβ invalid URL
Parameters
torrent_hash(str | None) β hash for the torrentorig_url(str | None) β the webseed URL that's getting replacednew_url(str | None) β the webseed URL to replace it with
Return type: None
torrents_export(torrent_hash=None, **kwargs) -> bytes
Export a .torrent file for the torrent β grab that little guy and take it with you π
This method was introduced with qBittorrent v4.5.0 (Web API v2.8.14).
Raises
NotFound404Errorβ torrent not foundConflict409Errorβ unable to export the.torrentfile π
Parameters
torrent_hash(str | None) β hash for the torrent
Return type: bytes
torrents_file_priority(torrent_hash=None, file_ids=None, priority=None, **kwargs) -> None
Set the priority for one or more files. Main character files get priority, obviously π
Raises
InvalidRequest400Errorβ if the priority is invalid or at least one file ID is not an integerNotFound404Errorβ πConflict409Errorβ if the torrent metadata hasn't finished downloading, or at least one file wasn't found
Parameters
torrent_hash(str | None) β hash for the torrentfile_ids(str | int | Iterable[str | int] | None) β a single file ID or a list of thempriority(str | int | None) β priority for the file(s) βhttps://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-5.0)#user-content-set-file-priority
Return type: None
torrents_files(torrent_hash=None, **kwargs) -> TorrentFilesList
Retrieve an individual torrent's files. Every single one, no cap π
Raises NotFound404Error β π
Parameters
torrent_hash(str | None) β hash for the torrent
Return type: TorrentFilesList
torrents_increase_priority(torrent_hashes=None, **kwargs) -> None
Bump a torrent's priority up β¬οΈβ¨ Heads up though: Torrent Queuing must be enabled for this to work, fr fr.
Raises Conflict409Error β π
Parameters
torrent_hashes(str | Iterable[str] | None) β a single torrent hash or a list of torrent hashes. Orallfor all torrents.
Return type: None
torrents_info(status_filter=None, category=None, sort=None, reverse=None, limit=None, offset=None, torrent_hashes=None, tag=None, private=None, include_trackers=None, include_files=None, **kwargs) -> TorrentInfoList
Retrieves a list of info for torrents. The whole scoop, bestie π
Parameters
status_filter(Literal['all', 'downloading', 'seeding', 'completed', 'paused', 'stopped', 'active', 'inactive', 'resumed', 'running', 'stalled', 'stalled_uploading', 'stalled_downloading', 'checking', 'moving', 'errored'] | None) β filter the list by torrent status:- Original options:
all,downloading,seeding,completed,paused,active,inactive,resumed,errored - Added in Web API v2.4.1:
stalled,stalled_uploading, andstalled_downloading - Added in Web API v2.8.4:
checking - Added in Web API v2.8.18:
moving - Added in Web API v2.11.0:
stopped(replacedpaused),running(replacedresumed)
- Original options:
category(str | None) β filter the list by categorysort(str | None) β sort the list by any property that gets returnedreverse(bool | None) β reverse the sorting πlimit(str | int | None) β limit how long the list isoffset(str | int | None) β where the list starts (if it's< 0, you offset from the end of the list)torrent_hashes(str | Iterable[str] | None) β filter the list by hash (separate multiple hashes with a'|') (added in Web API v2.0.1)tag(str | None) β filter the list by tag (empty string means "untagged"; no"tag"parameter means "any tag"; added in Web API v2.8.3)private(bool | None) β filter the list by the private flag β useNoneto ignore it (added in Web API v2.11.1)include_trackers(bool | None) β include trackers in the response; defaultFalse(added in Web API v2.11.4)include_files(bool | None) β include files in the response; defaultFalse(added in Web API v2.11.7)
Return type: TorrentInfoList
torrents_pause(torrent_hashes=None, **kwargs) -> None
Stop one or more torrents in qBittorrent. Sit down, bestie, take a break πβ
Parameters
torrent_hashes(str | Iterable[str] | None) β a single torrent hash or a list of torrent hashes. Orallfor all torrents.
Return type: None
torrents_piece_hashes(torrent_hash=None, **kwargs) -> TorrentPieceInfoList
Retrieve an individual torrent's pieces' hashes π§©
Raises NotFound404Error β π
Parameters
torrent_hash(str | None) β hash for the torrent
Return type: TorrentPieceInfoList
torrents_piece_states(torrent_hash=None, **kwargs) -> TorrentPieceInfoList
Retrieve an individual torrent's pieces' states π§©β¨
Raises NotFound404Error β π
Parameters
torrent_hash(str | None) β hash for the torrent
Return type: TorrentPieceInfoList
torrents_properties(torrent_hash=None, **kwargs) -> TorrentPropertiesDictionary
Retrieve an individual torrent's properties β all the juicy details π
Raises NotFound404Error β π
Parameters
torrent_hash(str | None) β hash for the torrent
Return type: TorrentPropertiesDictionary
torrents_reannounce(torrent_hashes=None, **kwargs) -> None
Reannounce a torrent. Gotta let the tracker know you're still here, periodt π£
This method was introduced with qBittorrent v4.1.2 (Web API v2.0.2).
β¦and the params for that last one are the classic little duo you already know: torrent_hashes (str | Iterable[str] | None) β so like, one single torrent hash, or a whole list of hashes, or all for all the torrents β and the return type is None. That's it. Nothing comes back. She ghosts you. π»
π torrents_recheck
torrents_recheck(torrent_hashes=None, **kwargs) -> None
Bestie, this one makes qBittorrent recheck a torrent. You know, verifying all the pieces like a suspicious friend going through your receipts π
Parameters
torrent_hashes(str | Iterable[str] | None) β single torrent hash or list of torrent hashes. Orallfor all torrents.
Return type: None
ποΈ torrents_remove_categories
torrents_remove_categories(categories=None, **kwargs) -> None
Deletes one or more categories. Poof. Gone. It's giving cleanup era π§Ήβ¨
Parameters
categories(str | Iterable[str] | None) β categories to delete
Return type: None
π·οΈ torrents_remove_tags
torrents_remove_tags(tags=None, torrent_hashes=None, **kwargs) -> None
Okay so the docstring literally says "Add one or more tags to one or more torrents." on the remove method and I'm just gonna read it to you exactly as written π (it's the remove one, the name is right there, we move).
This method was introduced with qBittorrent v4.2.0 (Web API v2.3.0).
Parameters
tags(str | Iterable[str] | None) β tag name or list of tagstorrent_hashes(str | Iterable[str] | None) β single torrent hash or list of torrent hashes. Orallfor all torrents.
Return type: None
βοΈ torrents_remove_trackers
torrents_remove_trackers(torrent_hash=None, urls=None, **kwargs) -> None
Remove trackers from a torrent. Bye tracker bestie, we hardly knew ye π«Ά
This method was introduced with qBittorrent v4.1.4 (Web API v2.2.0).
Raises
NotFound404ErrorβConflict409Errorβ
Parameters
torrent_hash(str | None) β hash for torrenturls(str | Iterable[str] | None) β tracker URLs to removed from torrent
Return type: None
π torrents_remove_webseeds
torrents_remove_webseeds(torrent_hash=None, urls=None, **kwargs) -> None
Remove webseeds from a torrent. Different from trackers, same dramatic exit energy π
Raises
NotFound404ErrorβInvalidRequest400Errorβ invalid URL
Parameters
torrent_hash(str | None) β hash for torrenturls(str | Iterable[str] | None) β list of webseed URLs to add to torrent
Return type: None
π·οΈ torrents_rename
torrents_rename(torrent_hash=None, new_torrent_name=None, **kwargs) -> None
Rename a torrent. Main character rebrand moment, honestly π
Raises NotFound404Error β
Parameters
torrent_hash(str | None) β hash for torrentnew_torrent_name(str | None) β new name for torrent
Return type: None
π torrents_rename_file
torrents_rename_file(torrent_hash=None, file_id=None, new_file_name=None, old_path=None, new_path=None, **kwargs) -> None
Rename a torrent file. Little glow-up for one specific file inside the torrent π
This method was introduced with qBittorrent v4.2.1 (Web API v2.4.0).
Raises
MissingRequiredParameters400ErrorβNotFound404ErrorβConflict409Errorβ
Parameters
torrent_hash(str | None) β hash for torrentfile_id(str | int | None) β id for file (removed in Web API v2.7)new_file_name(str | None) β new name for file (removed in Web API v2.7)old_path(str | None) β path of file to rename (added in Web API v2.7)new_path(str | None) β new path of file to rename (added in Web API v2.7)
Heads up bestie βfile_idandnew_file_namegot removed in Web API v2.7, andold_path+new_pathgot added in Web API v2.7. So which params you actually pass lowkey depends on your version. Version check first, always π«‘
Return type: None
π torrents_rename_folder
torrents_rename_folder(torrent_hash=None, old_path=None, new_path=None, **kwargs) -> None
Rename a torrent folder. Whole folder gets a new name, it's giving rebrand β¨
This method was introduced with qBittorrent v4.3.2 (Web API v2.7).
Raises
MissingRequiredParameters400ErrorβNotFound404ErrorβConflict409Errorβ
Parameters
torrent_hash(str | None) β hash for torrentold_path(str | None) β path of file to rename (added in Web API v2.7)new_path(str | None) β new path of file to rename (added in Web API v2.7)
Return type: None
βΆοΈ torrents_resume
torrents_resume(torrent_hashes=None, **kwargs) -> None
Start one or more torrents in qBittorrent. Wake up babe, we're downloading again π
Parameters
torrent_hashes(str | Iterable[str] | None) β single torrent hash or list of torrent hashes. Orallfor all torrents.
Return type: None
π€ torrents_set_auto_management
torrents_set_auto_management(enable=None, torrent_hashes=None, **kwargs) -> None
Enable or disable automatic torrent management for one or more torrents. Let the machine take the wheel or grab the wheel back, your call π₯
Parameters
torrent_hashes(str | Iterable[str] | None) β single torrent hash or list of torrent hashes. Orallfor all torrents.enable(bool | None) β Defaults toTrueifNoneor unset; useFalseto disable
Return type: None
ποΈ torrents_set_category
torrents_set_category(category=None, torrent_hashes=None, **kwargs) -> None
Set a category for one or more torrents. Organising is self care, periodt πΈ
Raises Conflict409Error β for bad category
Parameters
torrent_hashes(str | Iterable[str] | None) β single torrent hash or list of torrent hashes. Orallfor all torrents.category(str | None) β category to assign to torrent
Return type: None
π¬ torrents_set_comment
torrents_set_comment(comment=None, torrent_hashes=None, **kwargs) -> None
Set a comment for one or more torrents. Leave a little note for future you π
Parameters
torrent_hashes(str | Iterable[str] | None) β single torrent hash or list of torrent hashes. Orallfor all torrents.comment(str | None) β comment to assign to torrent
Return type: None
π torrents_set_download_limit
torrents_set_download_limit(limit=None, torrent_hashes=None, **kwargs) -> None
Set the download limit for one or more torrents. Throttle it or unleash it, no in between π
Parameters
torrent_hashes(str | Iterable[str] | None) β single torrent hash or list of torrent hashes. Orallfor all torrents.limit(str | int | None) β bytes/second (-1sets the limit to infinity)
π₯ torrents_set_download_path
torrents_set_download_path(download_path=None, torrent_hashes=None, **kwargs) -> None
Set the Download Path for one or more torrents β like, where the torrent contents chill before the torrent finishes downloading.
This method was introduced with qBittorrent v4.4.0 (Web API v2.8.4).
Raises
Forbidden403Errorβ cannot write to directoryConflict409Errorβ cannot create directory
Parameters
download_path(str | None) β file path to save torrent contents before torrent finishes downloadingtorrent_hashes(str | Iterable[str] | None) β single torrent hash or list of torrent hashes. Orallfor all torrents.
Return type: None
β‘ torrents_set_force_start
torrents_set_force_start(enable=None, torrent_hashes=None, **kwargs) -> None
Force start one or more torrents. Not a vibe check, an override π₯
Parameters
torrent_hashes(str | Iterable[str] | None) β single torrent hash or list of torrent hashes. Orallfor all torrents.enable(bool | None) β Defaults toTrueifNoneor unset;Falseis equivalent totorrents_resume().
Return type: None
π¦ torrents_set_location
torrents_set_location(location=None, torrent_hashes=None, **kwargs) -> None
Set location for torrents' files. Basically moving day for your data π
Raises
Forbidden403Errorβ if the user doesn't have permissions to write to the location (only before v4.5.2 - write check was removed.)Conflict409Errorβ if the directory cannot be created at the location
Parameters
torrent_hashes(str | Iterable[str] | None) β single torrent hash or list of torrent hashes. Orallfor all torrents.location(str | None) β disk location to move torrent's files
Return type: None
πΎ torrents_set_save_path
torrents_set_save_path(save_path=None, torrent_hashes=None, **kwargs) -> None
Set the Save Path for one or more torrents.
This method was introduced with qBittorrent v4.4.0 (Web API v2.8.4).
Raises
Forbidden403Errorβ cannot write to directoryConflict409Errorβ cannot create directory
Parameters
π torrents_set_share_limits()
torrents_set_share_limits(ratio_limit=None, seeding_time_limit=None, inactive_seeding_time_limit=None, share_limit_action=None, torrent_hashes=None, **kwargs) -> None
Okay so this one sets the share limits for one or more torrents β like, "how much do I care before I stop seeding this thing" energy π«Ά
This method was introduced with qBittorrent v4.1.1 (Web API v2.0.1).
Parameters
torrent_hashes(str | Iterable[str] | None) β single torrent hash or list of torrent hashes. Orallfor all torrents.ratio_limit(str | int | None) β max ratio to seed a torrent. (-2means use the global value and-1is no limit)seeding_time_limit(str | int | None) β minutes (-2means use the global value and-1is no limit)inactive_seeding_time_limit(str | int | None) β minutes (-2means use the global value and-1is no limit) (added in Web API v2.9.2)
Return type
None
πΈ torrents_set_super_seeding()
torrents_set_super_seeding(enable=None, torrent_hashes=None, **kwargs) -> None
Marks one or more torrents as super seeding β¨
Parameters
torrent_hashes(str | Iterable[str] | None) β single torrent hash or list of torrent hashes. Orallfor all torrents.enable(bool | None) β Defaults toTrueifNoneor unset;Falseto disable
Return type
None
π
torrents_set_tags()
torrents_set_tags(tags=None, torrent_hashes=None, **kwargs) -> None
Upserts one or more tags onto one or more torrents, bestie π·οΈ
Note: Tags that do not exist will be created on-the-fly.
This method was introduced with qBittorrent v5.1.0 (Web API v2.11.4).
Parameters
tags(str | Iterable[str] | None) β tag name or list of tagstorrent_hashes(str | Iterable[str] | None) β single torrent hash or list of torrent hashes. Orallfor all torrents.
Return type
None
π¦ torrents_set_upload_limit()
torrents_set_upload_limit(limit=None, torrent_hashes=None, **kwargs) -> None
Sets the upload limit for one or more torrents β throttle her gently π
Parameters
torrent_hashes(str | Iterable[str] | None) β single torrent hash or list of torrent hashes. Orallfor all torrents.limit(str | int | None) β bytes/second (-1sets the limit to infinity)
Return type
None
β torrents_start()
torrents_start(torrent_hashes=None, **kwargs) -> None
Starts one or more torrents in qBittorrent β go go go π₯
Parameters
torrent_hashes (str | Iterable[str] | None) β single torrent hash or list of torrent hashes. Or all for all torrents.
Return type
None
π torrents_stop()
torrents_stop(torrent_hashes=None, **kwargs) -> None
Stops one or more torrents in qBittorrent β nap time π΄
Parameters
torrent_hashes (str | Iterable[str] | None) β single torrent hash or list of torrent hashes. Or all for all torrents.
Return type
None
π torrents_tags()
torrents_tags(**kwargs) -> TagList
Retrieves, like, all the tag definitions. Every single one π
This method was introduced with qBittorrent v4.2.0 (Web API v2.3.0).
Return type
TagList
π§ torrents_toggle_first_last_piece_priority()
torrents_toggle_first_last_piece_priority(torrent_hashes=None, **kwargs) -> None
Toggles the priority of first/last piece downloading β very niche, very iconic β¨
Parameters
torrent_hashes (str | Iterable[str] | None) β single torrent hash or list of torrent hashes. Or all for all torrents.
Return type
None
π torrents_toggle_sequential_download()
torrents_toggle_sequential_download(torrent_hashes=None, **kwargs) -> None
Toggles sequential download for one or more torrents β in order, no chaos π
Parameters
torrent_hashes (str | Iterable[str] | None) β single torrent hash or list of torrent hashes. Or all for all torrents.
Return type
None
π torrents_top_priority()
torrents_top_priority(torrent_hashes=None, **kwargs) -> None
Sets a torrent as the highest priority. Torrent Queuing must be enabled, no cap β οΈ
Raises Conflict409Error
Parameters
torrent_hashes (str | Iterable[str] | None) β single torrent hash or list of torrent hashes. Or all for all torrents.
Return type
None
π torrents_trackers()
torrents_trackers(torrent_hash=None, **kwargs) -> TrackersList
Grabs one individual torrent's trackers. Tracker status is defined in TrackerStatus β iykyk π
Raises NotFound404Error
Parameters
torrent_hash (str | None) β hash for torrent
Return type
TrackersList
π torrents_upload_limit()
torrents_upload_limit(torrent_hashes=None, **kwargs) -> TorrentLimitsDictionary
Reads back the upload limit for one or more torrents π«Ά
Parameters
torrent_hashes (str | Iterable[str] | None) β single torrent hash or list of torrent hashes. Or all for all torrents.
Return type
TorrentLimitsDictionary
πΈ torrents_webseeds()
torrents_webseeds(torrent_hash=None, **kwargs) -> WebSeedsList
Grabs one individual torrent's web seeds π±
Raises NotFound404Error β torrent not found
Parameters
torrent_hash (str | None) β hash for torrent
Return type
WebSeedsList
π class Torrents(client) -> None
class Torrents(client) -> None
Allows interaction with the Torrents API endpoints. Main character class fr fr π
β¨ Usage
>>> from qbittorrentapi import Client
>>> client = Client(host="localhost:8080", username="admin", password="adminadmin")
>>> # these are all the same attributes that are available as named in the
>>> # endpoints or the more pythonic names in Client (with or without 'torrents_' prepended)
>>> torrent_list = client.torrents.info()
>>> torrent_list_active = client.torrents.info.active()
>>> torrent_list_active_partial = client.torrents.info.active(limit=100, offset=200)
>>> torrent_list_downloading = client.torrents.info.downloading()
>>> # torrent looping
>>> for torrent in client.torrents.info.completed()
>>> # all torrents endpoints with a 'hashes' parameters support all method to apply action to all torrents
>>> client.torrents.stop.all()
>>> client.torrents.start.all()
>>> # or specify the individual hashes
>>> client.torrents.downloadLimit(torrent_hashes=["...", "..."])
π«Ά add()
add(urls=None, torrent_files=None, save_path=None, cookie=None, category=None, is_skip_checking=None, is_paused=None, is_root_folder=None, rename=None, upload_limit=None, download_limit=None, use_auto_torrent_management=None, is_sequential_download=None, is_first_last_piece_priority=None, tags=None, content_layout=None, ratio_limit=None, seeding_time_limit=None, download_path=None, use_download_path=None, stop_condition=None, add_to_top_of_queue=None, inactive_seeding_time_limit=None, share_limit_action=None, ssl_certificate=None, ssl_private_key=None, ssl_dh_params=None, is_stopped=None, **kwargs) -> str | TorrentsAddedMetadata
Implements torrents_add(). Yes the parameter list is enormous, she ate π
Return type
str | TorrentsAddedMetadata
π add_trackers()
add_trackers(torrent_hash=None, urls=None, **kwargs) -> None
Implements torrents_add_trackers().
Return type
None
π¦ add_webseeds()
add_webseeds(torrent_hash=None, urls=None, **kwargs) -> None
Implements torrents_add_webseeds().
Return type
None
β count()
count() -> int
Implements torrents_count().
Return type
int
π
edit_tracker()
edit_tracker(torrent_hash=None, original_url=None, new_url=None, tier=None, **kwargs) -> None
Implements torrents_edit_tracker().
Return type
None
π edit_webseed()
edit_webseed(torrent_hash=None, orig_url=None, new_url=None, **kwargs) -> None
Implements torrents_edit_webseed(). (Yes, orig_url β not original_url. Not me getting those mixed up π)
Return type
None
π export()
export(torrent_hash=None, **kwargs) -> bytes
Implements torrents_export().
Return type
bytes
π§ file_priority()
file_priority(torrent_hash=None, file_ids=None, priority=None, **kwargs) -> None
Implements torrents_file_priority().
Return type
None
π files()
files(torrent_hash=None, **kwargs) -> TorrentFilesList
Implements torrents_files().
Return type
TorrentFilesList
π₯ piece_hashes()
piece_hashes(torrent_hash=None, **kwargs) -> TorrentPieceInfoList
Implements torrents_piece_hashes().
Return type
TorrentPieceInfoList
piece_states(torrent_hash=None, **kwargs) -> TorrentPieceInfoListβ the vibe-check twin oftorrents_piece_states(). Returns aTorrentPieceInfoList. π§©properties(torrent_hash=None, **kwargs) -> TorrentPropertiesDictionaryβ this one just wrapstorrents_properties()and hands you back a wholeTorrentPropertiesDictionary. It's giving "the full lore". πremove_trackers(torrent_hash=None, urls=None, **kwargs) -> Noneβ implementstorrents_remove_trackers(). ReturnsNone(blocked, unfollowed, bye β¨).remove_webseeds(torrent_hash=None, urls=None, **kwargs) -> Noneβ implementstorrents_remove_webseeds(). ReturnsNone. πͺ£rename(torrent_hash=None, new_torrent_name=None, **kwargs) -> Noneβ implementstorrents_rename(). ReturnsNone. Name change era πrename_file(torrent_hash=None, file_id=None, new_file_name=None, old_path=None, new_path=None, **kwargs) -> Noneβ implementstorrents_rename_file(). ReturnsNone. Yes bestie,file_id,new_file_name,old_pathandnew_pathβ all four, no skipping. πrename_folder(torrent_hash=None, old_path=None, new_path=None, **kwargs) -> Noneβ implementstorrents_rename_folder(). ReturnsNone. Folder glow-up unlocked πtrackers(torrent_hash=None, **kwargs) -> TrackersListβ implementstorrents_trackers(). Returns aTrackersList. No cap, there are so many trackers. πwebseeds(torrent_hash=None, **kwargs) -> WebSeedsListβ implementstorrents_webseeds(). Returns aWebSeedsList. The webseed lore, delivered. π±
πΈ class TorrentDictionary(data, client) -> None
Bases: ClientCache[TorrentsAPIMixIn], ListEntry
Okay so this is literally the main character: an item in TorrentInfoList that lets you interact with individual torrents through the Torrents API endpoints. One torrent, all the buttons. π«Ά
The way that all torrent attributes are listed in β https://github.com/qbittorrent/qBittorrent/blob/master/src/webui/api/serialize/serialize_torrent.h β yeah, that's the source of truth, go peek iykyk π
Usage π«
>>> from qbittorrentapi import Client
>>> client = Client(host="localhost:8080", username="admin", password="adminadmin")
>>> # these are all the same attributes that are available as named in the
>>> # endpoints or the more pythonic names in Client (with or without 'transfer_' prepended)
>>> torrent = client.torrents.info()[0]
>>> torrent_id = torrent.hash # truncated v2 hash or v1 hash
>>> torrent_hash_v1 = torrent.infohash_v1
>>> torrent_hash_v2 = torrent.infohash_v2
>>> torrent_magnet = torrent.magnet_uri
>>> torrent_name = torrent.name
>>> # Attributes without inputs and a return value are properties
>>> properties = torrent.properties
>>> trackers = torrent.trackers
>>> files = torrent.files
>>> # Action methods
>>> torrent.edit_tracker(original_url="...", new_url="...")
>>> torrent.remove_trackers(urls="http://127.0.0.2/")
>>> torrent.rename(new_torrent_name="...")
>>> torrent.start()
>>> torrent.stop()
>>> torrent.recheck()
>>> torrent.torrents_top_priority()
>>> torrent.setLocation(location="/home/user/torrents/")
>>> torrent.setCategory(category="video")
π¦ The methods, in order, no skips
add_tags(tags=None, **kwargs) -> Noneβ implementstorrents_add_tags(). ReturnsNone. Tag it, slay it. π·οΈadd_trackers(urls=None, **kwargs) -> Noneβ implementstorrents_add_trackers(). ReturnsNone.add_webseeds(urls, **kwargs) -> Noneβ implementstorrents_add_webseeds(). ReturnsNone. Heads up bestie:urlshere has no default value, unlike its neighbours. πbottom_priority(**kwargs) -> Noneβ implementstorrents_bottom_priority(). ReturnsNone. Straight to the bottom of the queue, no notes. β¬οΈdecrease_priority(**kwargs) -> Noneβ implementstorrents_decrease_priority(). ReturnsNone.delete(delete_files=None, **kwargs) -> Noneβ implementstorrents_delete(). ReturnsNone. Whether the actual files get deleted rides ondelete_filesβ choose wisely π- property
download_limit: intβ implementstorrents_download_limit(). It's a property, so no call parens, just vibes. π¦ edit_tracker(orig_url=None, new_url=None, tier=None, **kwargs) -> Noneβ implementstorrents_edit_tracker(). ReturnsNone. Note the parameter isorig_urlhere (notoriginal_urllike in the usage snippet above β fr fr, read both). βοΈedit_webseed(orig_url=None, new_url=None, **kwargs) -> Noneβ implementstorrents_edit_webseed(). ReturnsNone.export(**kwargs) -> bytesβ implementstorrents_export(). Returnsbytesβ actual raw torrent bytes, iconic. π¦file_priority(file_ids=None, priority=None, **kwargs) -> Noneβ implementstorrents_file_priority(). ReturnsNone.- property
files: TorrentFilesListβ implementstorrents_files(). Get the file list without even calling anything. ποΈ increase_priority(**kwargs) -> Noneβ implementstorrents_increase_priority(). ReturnsNone. Moving up in the world β¬οΈ- property
info: TorrentDictionaryβ returns data fromtorrents_info()for the torrent. Yes, a torrent can hand you back its own info. Recursive queen. π pause(**kwargs) -> Noneβ implementstorrents_stop(). ReturnsNone. Pause = stop under the hood, that's just how it is. βΈοΈ- property
piece_hashes: TorrentPieceInfoListβ implementstorrents_piece_hashes(). - property
piece_states: TorrentPieceInfoListβ implementstorrents_piece_states(). - property
properties: TorrentPropertiesDictionaryβ implementstorrents_properties(). reannounce(**kwargs) -> Noneβ implementstorrents_reannounce(). ReturnsNone. Go talk to the trackers again, bestie π’recheck(**kwargs) -> Noneβ implementstorrents_recheck(). ReturnsNone. Hashing era πremove_tags(tags=None, **kwargs) -> Noneβ implementstorrents_remove_tags(). ReturnsNone.remove_trackers(urls=None, **kwargs) -> Noneβ implementstorrents_remove_trackers(). ReturnsNone.remove_webseeds(urls=None, **kwargs) -> Noneβ implementstorrents_remove_webseeds(). ReturnsNone.rename(new_name=None, **kwargs) -> Noneβ implementstorrents_rename(). ReturnsNone. Note: this one takesnew_name(the class-level mixin version tooknew_torrent_nameβ keep them straight π ).rename_file(file_id=None, new_file_name=None, old_path=None, new_path=None, **kwargs) -> Noneβ implementstorrents_rename_file(). ReturnsNone.rename_folder(old_path=None, new_path=None, **kwargs) -> Noneβ implementstorrents_rename_folder(). ReturnsNone.resume(**kwargs) -> Noneβ implementstorrents_start(). ReturnsNone. Resume = start, they're the same thing here π«ΆsetComment(comment=None, **kwargs) -> Noneβ implementstorrents_set_comment(). ReturnsNone. Yep, camelCase version exists too, legacy bestie πͺset_auto_management(enable=None, **kwargs) -> Noneβ implementstorrents_set_auto_management(). ReturnsNone.set_category(category=None, **kwargs) -> Noneβ implementstorrents_set_category(). ReturnsNone.set_comment(comment=None, **kwargs) -> Noneβ implementstorrents_set_comment(). ReturnsNone. The snake_case twin ofsetComment. πset_download_limit(limit=None, **kwargs) -> Noneβ implementstorrents_set_download_limit(). ReturnsNone.set_download_path(download_path=None, **kwargs) -> Noneβ implementstorrents_set_download_path(). ReturnsNone.set_force_start(enable=None, **kwargs) -> Noneβ implementstorrents_set_force_start(). ReturnsNone.set_location(location=None, **kwargs) -> Noneβ implementstorrents_set_location(). ReturnsNone. Move the whole thing somewhere new πset_save_path(save_path=None, **kwargs) -> Noneβ implementstorrents_set_save_path(). ReturnsNone.set_share_limits(ratio_limit=None, seeding_time_limit=None, inactive_seeding_time_limit=None, **kwargs) -> Noneβ implementstorrents_set_share_limits(). ReturnsNone. Three separate limits, all optional, all yours. βοΈset_super_seeding(enable=None, **kwargs) -> Noneβ implementstorrents_set_super_seeding(). ReturnsNone. Super seeding?? super slay π¦Έset_tags(tags=None, **kwargs) -> Noneβ implementstorrents_set_tags(). ReturnsNone.set_upload_limit(limit=None, **kwargs) -> Noneβ implementstorrents_set_upload_limit(). ReturnsNone.start(**kwargs) -> Noneβ implementstorrents_start(). ReturnsNone. Go go go π₯- property
state_enum: TorrentStateβ torrent state enum. The enum-ified state, no string guessing. π stop(**kwargs) -> Noneβ implementstorrents_stop(). ReturnsNone.sync_local() -> Noneβ update local cache of torrent info. ReturnsNone. Takes no kwargs, just does the thing. πtoggle_first_last_piece_priority(**kwargs) -> Noneβ implementstorrents_toggle_first_last_piece_priority(). ReturnsNone.toggle_sequential_download(**kwargs) -> Noneβ implementstorrents_toggle_sequential_download(). Flip that sequential-download switch, bestie. π
Return type: None π
top_priority(**kwargs) -> Noneβ Implementstorrents_top_priority().- Return type:
None
- Return type:
property trackers: TrackersListβ Implementstorrents_trackers().property upload_limit: intβ Implementstorrents_upload_limit().property webseeds: WebSeedsListβ Implementstorrents_webseeds().
π class TorrentCategories(*args, client, **kwargs) π
Bases: ClientCache[TorrentsAPIMixIn]
Allows interaction with torrent categories within the Torrents API endpoints. Itβs giving βorganize your whole downloads folder era.β π
Usage
>>> from qbittorrentapi import Client
>>> client = Client(host="localhost:8080", username="admin", password="adminadmin")
>>> # these are all the same attributes that are available as named in the
>>> # endpoints or the more pythonic names in Client (with or without 'torrents_' prepended)
>>> categories = client.torrent_categories.categories
>>> # create or edit categories
>>> client.torrent_categories.create_category(name="Video", save_path="/home/user/torrents/Video")
>>> client.torrent_categories.edit_category(name="Video", save_path="/data/torrents/Video")
>>> # edit or create new by assignment
>>> client.torrent_categories.categories = dict(name="Video", save_path="/hone/user/")
>>> # delete categories
>>> client.torrent_categories.removeCategories(categories="Video")
>>> client.torrent_categories.removeCategories(categories=["Audio", "ISOs"])
property categories: TorrentCategoriesDictionaryβ Implementstorrents_categories().create_category(name=None, save_path=None, download_path=None, enable_download_path=None, **kwargs) -> Noneβ Implementstorrents_create_category().- Return type:
None
- Return type:
edit_category(name=None, save_path=None, download_path=None, enable_download_path=None, **kwargs) -> Noneβ Implementstorrents_edit_category().- Return type:
None
- Return type:
remove_categories(categories=None, **kwargs) -> Noneβ Implementstorrents_remove_categories().- Return type:
None
- Return type:
π¦ class TorrentTags(*args, client, **kwargs) π¦
Bases: ClientCache[TorrentsAPIMixIn]
Allows interaction with torrent tags within the "Torrent" API endpoints. Tag your faves, bestie β itβs self-care. πΈ
Usage:
>>> from qbittorrentapi import Client
>>> client = Client(host="localhost:8080", username="admin", password="adminadmin")
>>> tags = client.torrent_tags.tags
>>> client.torrent_tags.tags = "tv show" # create category
>>> client.torrent_tags.create_tags(tags=["tv show", "linux distro"])
>>> client.torrent_tags.delete_tags(tags="tv show")
add_tags(tags=None, torrent_hashes=None, **kwargs) -> Noneβ Implementstorrents_add_tags().- Return type:
None
- Return type:
create_tags(tags=None, **kwargs) -> Noneβ Implementstorrents_create_tags().- Return type:
None
- Return type:
delete_tags(tags=None, **kwargs) -> Noneβ Implementstorrents_delete_tags().- Return type:
None
- Return type:
remove_tags(tags=None, torrent_hashes=None, **kwargs) -> Noneβ Implementstorrents_remove_tags().- Return type:
None
- Return type:
set_tags(tags=None, torrent_hashes=None, **kwargs) -> Noneβ Implementstorrents_set_tags().- Return type:
None
- Return type:
property tags: TagListβ Implementstorrents_tags().
π class TorrentPropertiesDictionary(data=None, **kwargs) π
Bases: Dictionary[None | int | str | bool | Sequence[JsonValueT] | Mapping[str, JsonValueT]]
Response to torrents_properties()
Definition: β https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-5.0)#user-content-get-torrent-generic-properties
π class TorrentLimitsDictionary(data=None, **kwargs) π
Bases: Dictionary[None | int | str | bool | Sequence[JsonValueT] | Mapping[str, JsonValueT]]
Response to torrents_download_limit()
π class TorrentCategoriesDictionary(data=None, **kwargs) π
Bases: Dictionary[None | int | str | bool | Sequence[JsonValueT] | Mapping[str, JsonValueT]]
Response to torrents_categories()
β class TorrentsAddPeersDictionary(data=None, **kwargs) β
Bases: Dictionary[None | int | str | bool | Sequence[JsonValueT] | Mapping[str, JsonValueT]]
Response to torrents_add_peers()
π class TorrentFilesList(list_entries, client=None) π
Bases: List[TorrentFile]
Response to torrents_files()
Definition: β https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-5.0)#user-content-get-torrent-contents
π§ class TorrentFile(data=None, **kwargs) π§
Bases: ListEntry
Item in TorrentFilesList
π¦ class WebSeedsList(list_entries, client=None) π¦
Bases: List[WebSeed]
Response to torrents_webseeds()
Definition: β https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-5.0)#user-content-get-torrent-web-seeds
π class WebSeed(data=None, **kwargs) π
Bases: ListEntry
Item in WebSeedsList
π class TrackersList(list_entries, client=None) π
Bases: List[Tracker]
Response to torrents_trackers()
Definition: β https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-5.0)#user-content-get-torrent-trackers
π«Ά class Tracker(data=None, **kwargs) π«Ά
Bases: ListEntry
Item in TrackersList
π₯ class TorrentInfoList(list_entries, client=None) π₯
Bases: List[TorrentDictionary]
Response to torrents_info()
Definition: β https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-5.0)#user-content-get-torrent-list
πΈ class TorrentPieceInfoList(list_entries, client=None) πΈ
Bases: List[TorrentPieceData]
Response to torrents_piece_states() and torrents_piece_hashes()
π class TorrentPieceData(data=None, **kwargs) π
Bases: ListEntry
Item in TorrentPieceInfoList
π class TagList(list_entries, client=None) π
Bases: List[Tag]
Response to torrents_tags()
π
class Tag(data=None, **kwargs) π
Bases: ListEntry
Item in TagList
π class TorrentsAddedMetadata(data=None, **kwargs) π
Bases: Dictionary[Any]
Response to torrents_add() for API v2.14.0+
π Transfer π
class TransferAPIMixIn(host=None, port=None, username=None, password=None, EXTRA_HEADERS=None, REQUESTS_ARGS=None, HTTPADAPTER_ARGS=None, VERIFY_WEBUI_CERTIFICATE=True, FORCE_SCHEME_FROM_HOST=False, RAISE_NOTIMPLEMENTEDERROR_FOR_UNIMPLEMENTED_API_ENDPOINTS=False, RAISE_ERROR_FOR_UNSUPPORTED_QBITTORRENT_VERSIONS=False, VERBOSE_RESPONSE_LOGGING=False, SIMPLE_RESPONSES=False, DISABLE_LOGGING_DEBUG_OUTPUT=False) -> None
Bases: AppAPIMixIn
Implementation of all Transfer API methods. Global transfer vibes only. β¨
Usage
>>> from qbittorrentapi import Client
>>> client = Client(host="localhost:8080", username="admin", password="adminadmin")
>>> transfer_info = client.transfer_info()
>>> client.transfer_set_download_limit(limit=1024000)
transfer_ban_peers(peers=None, **kwargs) -> Noneβ Ban one or more peers. This method was introduced with qBittorrent v4.2.0 (Web API v2.3.0).- Parameters:
peers (str | Iterable[str] | None)-- one or more peers to ban. each peer should take the form'host:port' - Return type:
None
- Parameters:
transfer_download_limit(**kwargs) -> intβ Retrieves download limit; 0 is unlimited.- Return type:
int
- Return type:
transfer_info(**kwargs) -> TransferInfoDictionaryβ Retrieves the global transfer info found in qBittorrent status bar.- Return type:
TransferInfoDictionary
- Return type:
transfer_setSpeedLimitsMode(intended_state=None, **kwargs) -> β Noneβ Sets whether alternative speed limits are enabled.- Parameters:
intended_state (bool | None)-- True to enable alt speed and False to disable. Leaving None will toggle the current state. - Return type:
None
- Parameters:
transfer_set_download_limit(limit=None, **kwargs) -> Noneβ Set the global download limit in bytes/second.- Parameters:
limit (str | int | None)-- download limit in bytes/second (0 or -1 for no limit) - Return type:
None
- Parameters:
transfer_set_speed_limits_mode(intended_state=None, **kwargs) -> Noneβ Sets whether alternative speed limits are enabled.- Parameters:
intended_state (bool | None)-- True to enable alt speed and False to disable. Leaving None will toggle the current state. - Return type:
None
- Parameters:
transfer_set_upload_limit(limit=None, **kwargs) -> Noneβ Set the global download limit in bytes/second.- Parameters:
limit (str | int | None)-- upload limit in bytes/second (0 or -1 for no limit) - Return type:
None
- Parameters:
transfer_speed_limits_mode(**kwargs) -> strβ Returns 1 if alternative speed limits are currently enabled, 0 otherwise.- Return type:
str
- Return type:
transfer_toggle_speed_limits_mode(intended_state=None, **kwargs) -> Noneβ Sets whether alternative speed limits are enabled.- Parameters:
intended_state (bool | None)-- True to enable alt speed and False to disable. Leaving None will toggle the current state.
- Parameters:
- Return type β
None
transfer_upload_limit(**kwargs) -> int
Grabs the upload limit for you β and bestie, if it comes back as 0, that means unlimited, not zero, okay? Don't panic. π
- Return type β
int
π class Transfer(*args, client, **kwargs)
The whole entire vibe for talking to the Transfer API endpoints. Like, all the bandwidth stuff lives here. β¨
Usage
>>> from qbittorrentapi import Client
>>> client = Client(host="localhost:8080", username="admin", password="adminadmin")
>>> # these are all the same attributes that are available as named in the
>>> # endpoints or the more pythonic names in Client (with or without 'transfer_' prepended)
>>> transfer_info = client.transfer.info
>>> # access and set download/upload limits as attributes
>>> dl_limit = client.transfer.download_limit
>>> # this updates qBittorrent in real-time
>>> client.transfer.download_limit = 1024000
>>> # update speed limits mode to alternate or not
>>> client.transfer.speedLimitsMode = True
ban_peers(peers=None, **kwargs) -> None
Under the hood it's just transfer_ban_peers(). Bye-bye peers, they had their chance. π
- Return type β
None
property download_limit: int
Basically transfer_download_limit() wearing a cuter outfit. π«Ά
property info: TransferInfoDictionary
It's transfer_info(), but as a property. Yes queen, attribute access.
set_download_limit(limit=None, **kwargs) -> None
Straight-up implements transfer_set_download_limit().
- Return type β
None
set_speed_limits_mode(intended_state=None, **kwargs) -> None
Implements transfer_set_speed_limits_mode().
- Return type β
None
set_upload_limit(limit=None, **kwargs) -> None
Implements transfer_set_upload_limit().
- Return type β
None
property speed_limits_mode: str
Implements transfer_speed_limits_mode().
toggle_speed_limits_mode(intended_state=None, **kwargs) -> None
Implements transfer_set_speed_limits_mode() β yes, same one as set_speed_limits_mode, that's not a typo, that's literally what it says. π
- Return type β
None
property upload_limit: int
Implements transfer_upload_limit().
π¦ class TransferInfoDictionary(data=None, **kwargs)
Bases: Dictionary[None | int | str | bool | Sequence[JsonValueT] | Mapping[str, JsonValueT]]
This lil cutie is what transfer_info() hands you back. πΈ
Definition: https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-5.0)#user-content-get-global-transfer-info
π Version
class Version
Okay so this is the glow-up for checking whether your Client can handle different versions of the qBittorrent app and its Web API. Version-vibe-check, iykyk. π
Ngl, heads up: if a version isn't listed as "supported" here, many (and honestly possibly all) methods are still likely to work fine, because the Web API is largely backwards and forward compatibleβ¦ albeit with some notable exceptions. So it's giving flexible, not flawless. π
classmethod is_api_version_supported(api_version) -> bool
Tells you whether a version of the qBittorrent Web API is fully supported by this API client.
- api_version (
str) β version of qBittorrent Web API version such as2.8.4 - Return type β
bool - Returns β
TrueorFalsefor whether version is supported β¨
classmethod is_app_version_supported(app_version) -> bool
Tells you whether a version of the qBittorrent application is fully supported by this API client.
- app_version (
str) β version of qBittorrent application such asv4.4.0 - Return type β
bool - Returns β
TrueorFalsefor whether version is supported π
classmethod latest_supported_api_version() -> str
The most recent version of qBittorrent Web API that's supported. Peak version. π₯
- Return type β
str
classmethod latest_supported_app_version() -> str
The most recent version of qBittorrent that's supported. She's the blueprint, fr fr. π
- Return type β
str
classmethod supported_api_versions() -> set[str]
A set of all the supported qBittorrent Web API versions. Collect them all. π
- Return type β
set[str]
classmethod supported_app_versions() -> set[str]
A set of all the supported qBittorrent application versions. π§
- Return type β
set[str]
π AUTHOR
Russell Martin β the main character who wrote all this. Respect. π«Ά
π COPYRIGHT
2026, Russell Martin
That's the whole manual, bestie β you made it to the end, and honestly? Iconic behavior. π
β¨ This page is 2026.5.0, dated May 05, 2026, and it's a QBITTORRENT-API(1) moment. Go forth and slay your transfer limits. π¦π
π¦ where this page comes from
- alpine 3.24: py3-qbittorrent-api-doc 2026.5.0-r0 Β· MIT
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms