QBITTORRENT-API(1)

πŸ“¦ version 2026.5.0, in alpine 3.24

πŸŽ€ 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 Client is created but calling auth_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_HOST
    • QBITTORRENTAPI_USERNAME
    • QBITTORRENTAPI_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 Client instantiation will create a new session in qBittorrent.
  • Therefore, if many Client instances will be created be sure to call auth_log_out for 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 Client with VERIFY_WEBUI_CERTIFICATE=False or set environment variable QBITTORRENTAPI_DO_NOT_VERIFY_WEBUI_CERTIFICATE to 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 Requests package 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 via timeout, or Cookies via cookies. 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.1 seconds and a read timeout of 30 seconds. 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 HTTPAdapter for the Session can be specified via the HTTPADAPTER_ARGS parameter for Client:
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 and None is returned.
  • To raise NotImplementedError instead, instantiate Client with:
qbt_client = Client(..., RAISE_NOTIMPLEMENTEDERROR_FOR_UNIMPLEMENTED_API_ENDPOINTS=True)

πŸ” qBittorrent Version Checking

  • It is also possible to either raise an Exception for 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 Client like below to raise UnsupportedQbittorrentVersion exception for versions not fully supported:
qbt_client = Client(..., RAISE_ERROR_FOR_UNSUPPORTED_QBITTORRENT_VERSIONS=True)
  • Additionally, Version can be used for manual introspection of the versions.
Version.is_app_version_supported(qbt_client.app.version)

πŸ”‡ Disable Logging Debug Output

  • Instantiate Client with DISABLE_LOGGING_DEBUG_OUTPUT=True or 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. Has http_status_code: int.
  • exception HTTP4XXError(*args, **kwargs) β€” Bases: HTTPError. Base error for all HTTP 4XX statuses.
  • exception HTTP5XXError(*args, **kwargs) β€” Bases: HTTPError. Base error for all HTTP 5XX statuses.
  • exception HTTP400Error(*args, **kwargs) β€” Bases: HTTP4XXError. HTTP 400 Status. http_status_code: int = 400.
  • exception HTTP401Error(*args, **kwargs) β€” Bases: HTTP4XXError. HTTP 401 Status. http_status_code: int = 401.
  • exception HTTP403Error(*args, **kwargs) β€” Bases: HTTP4XXError. HTTP 403 Status. http_status_code: int = 403.
  • exception HTTP404Error(*args, **kwargs) β€” Bases: HTTP4XXError. HTTP 404 Status. http_status_code: int = 404.
  • exception HTTP405Error(*args, **kwargs) β€” Bases: HTTP4XXError. HTTP 405 Status. http_status_code: int = 405.
  • exception HTTP409Error(*args, **kwargs) β€” Bases: HTTP4XXError. HTTP 409 Status. http_status_code: int = 409.
  • exception HTTP415Error(*args, **kwargs) β€” Bases: HTTP4XXError. HTTP 415 Status. http_status_code: int = 415.
  • exception HTTP500Error(*args, **kwargs) β€” Bases: HTTP5XXError. HTTP 500 Status. 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/add endpoint 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 directory
  • with_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().

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 be get, items, keys, values, mro, and register).

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_type is not None, 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 the torrents_files() method, may need to convert a large payload. Set this to True to get the simple JSON back. Alternatively, set it to True only 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 to False to skip certificate verification for HTTPS connections; for instance, if the connection is using a self-signed certificate. ⚠️ Not setting this to False for self-signed certs will cause an APIConnectionError exception to be raised.
  • EXTRA_HEADERS (Mapping[str, str] | None) β€” dictionary of HTTP headers to include in all requests made to qBittorrent
  • REQUESTS_ARGS (Mapping[str, Any] | None) β€” dictionary of configuration for each HTTP request made by requests.request
  • HTTPADAPTER_ARGS (Mapping[str, Any] | None) β€” dictionary of configuration for HTTPAdapter
  • FORCE_SCHEME_FROM_HOST (bool) β€” if a scheme (i.e. http or https) is specified in host, 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 to False.
  • RAISE_NOTIMPLEMENTEDERROR_FOR_UNIMPLEMENTED_API_ENDPOINTS (bool) β€” some endpoints may not be implemented in older versions of qBittorrent. Setting this to True will raise a NotImplementedError instead of just returning None.
  • RAISE_ERROR_FOR_UNSUPPORTED_QBITTORRENT_VERSIONS (bool) β€” raise UnsupportedQbittorrentVersion if the connected version of qBittorrent is not fully supported by this client. Defaults to False.
  • DISABLE_LOGGING_DEBUG_OUTPUT (bool) β€” turns off debug output from logging for this package as well as requests & 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_UPLOAD was renamed to STOPPED_UPLOAD - PAUSED_DOWNLOAD was renamed to STOPPED_DOWNLOAD

Definitions:

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' β€” pausedDL was renamed to stoppedDL in Web API v2.11.0
  • PAUSED_UPLOAD = 'pausedUP' β€” pausedUP was renamed to stoppedUP in Web API v2.11.0
  • QUEUED_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 you True when the State is categorized as Checking πŸ‘€
  • property is_complete: bool β€” gives you True when the State is categorized as Complete βœ…
  • property is_downloading: bool β€” gives you True when the State is categorized as Downloading ⬇️
  • property is_errored: bool β€” gives you True when the State is categorized as Errored πŸ’€
  • property is_paused: bool β€” literally just an alias of TorrentState.is_stopped, same vibe different name 🫢
  • property is_stopped: bool β€” gives you True when the State is categorized as Stopped πŸ›‘
  • property is_uploading: bool β€” gives you True when 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:

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 = 0
  • NOT_CONTACTED = 1
  • NOT_WORKING = 4
  • UPDATING = 3
  • WORKING = 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) β€” False to exclude normal entries
    • info (bool | None) β€” False to exclude info entries
    • warning (bool | None) β€” False to exclude warning entries
    • critical (bool | None) β€” False to exclude critical entries
    • last_known_id (str | int | None) β€” only entries with an ID greater than this value will be returned
    • Return type: LogMainList
  • 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

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 β€” implements log_main().
      • Return type: LogMainList
    • critical(last_known_id=None, **kwargs) -> LogMainList β€” implements log_main() with info=False, normal=False, and warning=False.
      • Return type: LogMainList
    • info(last_known_id=None, **kwargs) -> LogMainList β€” implements log_main().
      • Return type: LogMainList
    • normal(last_known_id=None, **kwargs) -> LogMainList β€” implements log_main() with info=False.
      • Return type: LogMainList
    • warning(last_known_id=None, **kwargs) -> LogMainList β€” implements log_main() with info=False and normal=False.
      • Return type: LogMainList
  • property main: Main β€” implements log_main() πŸ’…
  • peers(last_known_id=None, **kwargs) -> LogPeersList β€” implements log_peers().
    • Return type: LogPeersList

The list/entry girlies 🧚

  • class LogPeersList(list_entries, client=None) β€” bases: List[LogPeer]. This is the response for log_peers().
  • class LogPeer(data=None, **kwargs) β€” bases: ListEntry. One single item in LogPeersList.
  • class LogMainList(list_entries, client=None) β€” bases: List[LogEntry]. This is the response to log_main().
  • class LogEntry(data=None, **kwargs) β€” bases: ListEntry. One single item in LogMainList.

πŸ”§ 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 to True by 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 to False, 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 to False may 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 request
  • requests_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 object
  • default_scheme (str) β€” default scheme to use for URL
  • alt_scheme (str) β€” alternative scheme to use for URL if default doesn’t work
  • headers (Mapping[str, str]) β€” HTTP headers for request
  • requests_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 API
  • response_class (type) β€” class to return response as; if none, response is returned
  • response_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 post
  • params (Mapping[str, Any] | None) β€” key value pairs to send with GET calls
  • data (Mapping[str, Any] | None) β€” key value pairs to send with POST calls
  • files (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. APINames or torrents)
  • 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. APINames or torrents)
  • 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_peers
  • version_introduced (str) β€” the Web API version the endpoint was introduced
  • version_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 convert
  • delimiter (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. APINames or torrents)
  • 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. APINames or torrents)
  • 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 post
  • api_namespace (APINames | str) β€” the namespace for the API endpoint (e.g. APINames or torrents)
  • api_method (str) β€” the name for the API endpoint (e.g. add)
  • requests_args (Mapping[str, Any] | None) β€” default location for Requests kwargs
  • requests_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 request
  • data (Mapping[str, Any] | None) β€” key/value pairs that get sent with a POST request
  • files (Mapping[str, bytes | tuple[str, bytes]] | None) β€” files going out with the request πŸ“Ž
  • response_class (type) β€” the class used to cast the API response, iykyk
  • kwargs (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) β€” True or False for 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 from rss_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 rule
  • new_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 feed
  • refresh_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 feed
  • refresh_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

Return type: None


rss_set_rule(rule_name=None, rule_def=None, **kwargs) -> None

Creates a new RSS auto-downloading rule πŸŽ€

Parameters

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 implements rss_items() ✨
    • Return type: RSSitemsDictionary
  • property with_data: RSSitemsDictionary β€” implements rss_items() with include_feed_data=True. yes bestie it just turns that flag on for you, no cap 🫢
  • property without_data: RSSitemsDictionary β€” implements rss_items() with include_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 β€” implements rss_add_feed().
    • Return type: None
  • add_folder(folder_path=None, **kwargs) -> None β€” implements rss_add_folder().
    • Return type: None
  • property items: Items β€” implements rss_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 β€” implements rss_mark_as_read().
    • Return type: None
  • matching_articles(rule_name=None, **kwargs) -> RSSitemsDictionary β€” implements rss_matching_articles().
    • Return type: RSSitemsDictionary
  • move_item(orig_item_path=None, new_item_path=None, **kwargs) -> None β€” implements rss_move_item().
    • Return type: None
  • refresh_item(item_path=None) -> None β€” implements rss_refresh_item().
    • Return type: None
  • remove_item(item_path=None, **kwargs) -> None β€” implements rss_remove_item().
    • Return type: None
  • remove_rule(rule_name=None, **kwargs) -> None β€” implements rss_remove_rule().
    • Return type: None
  • rename_rule(orig_rule_name=None, new_rule_name=None, **kwargs) -> None β€” implements rss_rename_rule().
    • Return type: None
  • property rules: RSSRulesDictionary β€” implements rss_rules().
  • setFeedRefreshInterval(item_path=None, refresh_interval=None) -> None β€” implements rss_set_feed_refresh_interval().
    • Return type: None
  • set_feed_refresh_interval(item_path=None, refresh_interval=None) -> None β€” implements rss_set_feed_refresh_interval().
    • Return type: None
  • set_feed_url(url=None, item_path=None, **kwargs) -> None β€” implements rss_set_feed_url().
    • Return type: None
  • set_rule(rule_name=None, rule_def=None, **kwargs) -> None β€” implements rss_set_rule().
    • Return type: None
quick note bestie: setFeedRefreshInterval and set_feed_refresh_interval are literally the same thing wearing two different outfits β€” both implement rss_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 πŸ¦‹


πŸ•΅οΈ 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) (supports all and enabled)

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 .torrent file 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 to True if None or unset; use False to 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:

  • NotFound404Error
  • Conflict409Error
  • 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 β€” implements search_categories(). Return type: SearchCategoriesList
  • delete(search_id=None, **kwargs) -> None β€” implements search_delete(). Return type: None
  • download_torrent(url=None, plugin=None, **kwargs) -> None β€” implements search_download_torrent(). Return type: None
  • enable_plugin(plugins=None, enable=None, **kwargs) -> None β€” implements search_enable_plugin(). Return type: None
  • install_plugin(sources=None, **kwargs) -> None β€” implements search_install_plugin(). Return type: None
  • property plugins: SearchPluginsList β€” implements search_plugins(). 🧩
  • results(search_id=None, limit=None, offset=None, **kwargs) -> SearchResultsDictionary β€” implements search_results(). Return type: SearchResultsDictionary
  • start(pattern=None, plugins=None, category=None, **kwargs) -> SearchJobDictionary β€” implements search_start(). Return type: SearchJobDictionary
  • status(search_id=None, **kwargs) -> SearchStatusesList β€” implements search_status(). Return type: SearchStatusesList
  • stop(search_id=None, **kwargs) -> None β€” implements search_stop(). Return type: None
  • uninstall_plugin(sources=None, **kwargs) -> None β€” implements search_uninstall_plugin(). Return type: None
  • update_plugins(**kwargs) -> None β€” implements search_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 β€” implements search_delete(). Return type: None
  • results(limit=None, offset=None, **kwargs) -> SearchResultsDictionary β€” implements search_results(). Return type: SearchResultsDictionary
  • status(**kwargs) -> SearchStatusesList β€” implements search_status(). Return type: SearchStatusesList
  • stop(**kwargs) -> None β€” implements search_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: SyncMainDataDictionary
  • sync_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

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: SyncMainDataDictionary
  • delta(**kwargs) -> SyncMainDataDictionary β€” implements sync_maindata() to return updates since the last call. Return type: SyncMainDataDictionary
  • reset_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 β€” implements sync_torrent_peers(). Return type: SyncTorrentPeersDictionary
  • delta(torrent_hash=None, **kwargs) -> SyncTorrentPeersDictionary β€” implements sync_torrent_peers() to return updates since the last call. Return type: SyncTorrentPeersDictionary
  • reset_rid() -> None β€” resets the RID so the next request includes everything. Return type: None

Then the properties on Sync itself:

  • property maindata: MainData β€” implements sync_maindata().
  • property torrentPeers: TorrentPeers β€” implements sync_torrent_peers().
  • property torrent_peers: TorrentPeers β€” implements sync_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 content
  • torrent_file_path (str | PathLike[Any] | None) β€” file path to save torrent
  • format (Literal['v1', 'v2', 'hybrid'] | None) β€” BitTorrent V1 or V2; defaults to "hybrid" format if None
  • start_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 files
  • piece_size (int | None) β€” size of the pieces
  • comment (str | None) β€” comment
  • trackers (str | list[str] | None) β€” list of trackers to add
  • url_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 found
  • Conflict409Error β€” 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 exist
  • TorrentFilePermissionError β€” if read permission is denied to torrent file
  • Conflict409Error β€” 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's bytes (or the filename just can't be determined), the value 'torrent__n' is used. 🫢
  • save_path (str | None) β€” where the torrent data gets saved
  • cookie (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) β€” True to skip hash checking
  • is_paused (bool | None) β€” adds the torrent in stopped state; it's an alias for is_stopped
  • is_root_folder (bool | None) β€” True or False to create a root folder (superseded by content_layout with 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/second
  • download_limit (str | int | None) β€” download limit in bytes/second
  • use_auto_torrent_management (bool | None) β€” True or False to use automatic torrent management
  • is_sequential_download (bool | None) β€” True or False for sequential download
  • is_first_last_piece_priority (bool | None) β€” True or False for first and last piece download priority
  • tags (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, Subfolder or NoSubfolder, 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.5 or 2.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 to save_path (added in Web API v2.8.4)
  • use_download_path (bool | None) β€” True or False for whether download_path should be used… defaults to True if download_path is specified (added in Web API v2.8.4)
  • stop_condition (Literal['MetadataReceived', 'FilesChecked'] | None) β€” MetadataReceived or FilesChecked, 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 for is_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. Or all for 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 tags
  • torrent_hashes (str | Iterable[str] | None) β€” a single torrent hash or a list of torrent hashes. Or all for 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 torrent
  • urls (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 torrent
  • urls (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. Or all for 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 category
  • save_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 category
  • enable_download_path (bool | None) β€” True or False to 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. Or all for 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 string all if you wanna hit every single torrent πŸ’…
  • delete_files (bool | None) β€” slam a True in 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 edit
  • save_path (str | None) β€” the new location to save files for this category
  • download_path (str | None) β€” download location for torrents that have this category
  • enable_download_path (bool | None) β€” True or False to 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 torrent
  • original_url (str | None) β€” the URL of the tracker that already exists
  • new_url (str | None) β€” the new URL that's replacing it
  • tier (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 found
  • Conflict409Error β€” orig_url is not a webseed for the torrent
  • InvalidRequest400Error β€” invalid URL

Parameters

  • torrent_hash (str | None) β€” hash for the torrent
  • orig_url (str | None) β€” the webseed URL that's getting replaced
  • new_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 found
  • Conflict409Error β€” unable to export the .torrent file 😭

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 integer
  • NotFound404Error β€” πŸ’€
  • 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 torrent
  • file_ids (str | int | Iterable[str | int] | None) β€” a single file ID or a list of them
  • priority (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. Or all for 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, and stalled_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 (replaced paused), running (replaced resumed)
  • category (str | None) β€” filter the list by category
  • sort (str | None) β€” sort the list by any property that gets returned
  • reverse (bool | None) β€” reverse the sorting πŸ”„
  • limit (str | int | None) β€” limit how long the list is
  • offset (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 β€” use None to ignore it (added in Web API v2.11.1)
  • include_trackers (bool | None) β€” include trackers in the response; default False (added in Web API v2.11.4)
  • include_files (bool | None) β€” include files in the response; default False (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. Or all for 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. Or all for 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 tags
  • torrent_hashes (str | Iterable[str] | None) β€” single torrent hash or list of torrent hashes. Or all for 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 torrent
  • urls (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 torrent
  • urls (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 torrent
  • new_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 torrent
  • file_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_id and new_file_name got removed in Web API v2.7, and old_path + new_path got 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 torrent
  • 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)

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. Or all for 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. Or all for all torrents.
  • enable (bool | None) β€” Defaults to True if None or unset; use False to 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. Or all for 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. Or all for 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. Or all for all torrents.
  • limit (str | int | None) β€” bytes/second (-1 sets 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 directory
  • Conflict409Error β€” cannot create directory

Parameters

  • download_path (str | None) β€” file path to save torrent contents before torrent finishes downloading
  • torrent_hashes (str | Iterable[str] | None) β€” single torrent hash or list of torrent hashes. Or all for 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. Or all for all torrents.
  • enable (bool | None) β€” Defaults to True if None or unset; False is equivalent to torrents_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. Or all for 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 directory
  • Conflict409Error β€” 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. Or all for all torrents.
  • ratio_limit (str | int | None) β€” max ratio to seed a torrent. (-2 means use the global value and -1 is no limit)
  • seeding_time_limit (str | int | None) β€” minutes (-2 means use the global value and -1 is no limit)
  • inactive_seeding_time_limit (str | int | None) β€” minutes (-2 means use the global value and -1 is 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. Or all for all torrents.
  • enable (bool | None) β€” Defaults to True if None or unset; False to 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 tags
  • torrent_hashes (str | Iterable[str] | None) β€” single torrent hash or list of torrent hashes. Or all for 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. Or all for all torrents.
  • limit (str | int | None) β€” bytes/second (-1 sets 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 of torrents_piece_states(). Returns a TorrentPieceInfoList. 🧩
  • properties(torrent_hash=None, **kwargs) -> TorrentPropertiesDictionary β€” this one just wraps torrents_properties() and hands you back a whole TorrentPropertiesDictionary. It's giving "the full lore". πŸ’…
  • remove_trackers(torrent_hash=None, urls=None, **kwargs) -> None β€” implements torrents_remove_trackers(). Returns None (blocked, unfollowed, bye ✨).
  • remove_webseeds(torrent_hash=None, urls=None, **kwargs) -> None β€” implements torrents_remove_webseeds(). Returns None. πŸͺ£
  • rename(torrent_hash=None, new_torrent_name=None, **kwargs) -> None β€” implements torrents_rename(). Returns None. Name change era πŸ‘‘
  • rename_file(torrent_hash=None, file_id=None, new_file_name=None, old_path=None, new_path=None, **kwargs) -> None β€” implements torrents_rename_file(). Returns None. Yes bestie, file_id, new_file_name, old_path and new_path β€” all four, no skipping. πŸ“
  • rename_folder(torrent_hash=None, old_path=None, new_path=None, **kwargs) -> None β€” implements torrents_rename_folder(). Returns None. Folder glow-up unlocked πŸŽ€
  • trackers(torrent_hash=None, **kwargs) -> TrackersList β€” implements torrents_trackers(). Returns a TrackersList. No cap, there are so many trackers. 🌐
  • webseeds(torrent_hash=None, **kwargs) -> WebSeedsList β€” implements torrents_webseeds(). Returns a WebSeedsList. 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 β€” implements torrents_add_tags(). Returns None. Tag it, slay it. 🏷️
  • add_trackers(urls=None, **kwargs) -> None β€” implements torrents_add_trackers(). Returns None.
  • add_webseeds(urls, **kwargs) -> None β€” implements torrents_add_webseeds(). Returns None. Heads up bestie: urls here has no default value, unlike its neighbours. πŸ™ˆ
  • bottom_priority(**kwargs) -> None β€” implements torrents_bottom_priority(). Returns None. Straight to the bottom of the queue, no notes. ⬇️
  • decrease_priority(**kwargs) -> None β€” implements torrents_decrease_priority(). Returns None.
  • delete(delete_files=None, **kwargs) -> None β€” implements torrents_delete(). Returns None. Whether the actual files get deleted rides on delete_files β€” choose wisely 😭
  • property download_limit: int β€” implements torrents_download_limit(). It's a property, so no call parens, just vibes. 🚦
  • edit_tracker(orig_url=None, new_url=None, tier=None, **kwargs) -> None β€” implements torrents_edit_tracker(). Returns None. Note the parameter is orig_url here (not original_url like in the usage snippet above β€” fr fr, read both). ✏️
  • edit_webseed(orig_url=None, new_url=None, **kwargs) -> None β€” implements torrents_edit_webseed(). Returns None.
  • export(**kwargs) -> bytes β€” implements torrents_export(). Returns bytes β€” actual raw torrent bytes, iconic. πŸ“¦
  • file_priority(file_ids=None, priority=None, **kwargs) -> None β€” implements torrents_file_priority(). Returns None.
  • property files: TorrentFilesList β€” implements torrents_files(). Get the file list without even calling anything. πŸ—‚οΈ
  • increase_priority(**kwargs) -> None β€” implements torrents_increase_priority(). Returns None. Moving up in the world ⬆️
  • property info: TorrentDictionary β€” returns data from torrents_info() for the torrent. Yes, a torrent can hand you back its own info. Recursive queen. πŸ‘‘
  • pause(**kwargs) -> None β€” implements torrents_stop(). Returns None. Pause = stop under the hood, that's just how it is. ⏸️
  • property piece_hashes: TorrentPieceInfoList β€” implements torrents_piece_hashes().
  • property piece_states: TorrentPieceInfoList β€” implements torrents_piece_states().
  • property properties: TorrentPropertiesDictionary β€” implements torrents_properties().
  • reannounce(**kwargs) -> None β€” implements torrents_reannounce(). Returns None. Go talk to the trackers again, bestie πŸ“’
  • recheck(**kwargs) -> None β€” implements torrents_recheck(). Returns None. Hashing era πŸ”
  • remove_tags(tags=None, **kwargs) -> None β€” implements torrents_remove_tags(). Returns None.
  • remove_trackers(urls=None, **kwargs) -> None β€” implements torrents_remove_trackers(). Returns None.
  • remove_webseeds(urls=None, **kwargs) -> None β€” implements torrents_remove_webseeds(). Returns None.
  • rename(new_name=None, **kwargs) -> None β€” implements torrents_rename(). Returns None. Note: this one takes new_name (the class-level mixin version took new_torrent_name β€” keep them straight πŸ’…).
  • rename_file(file_id=None, new_file_name=None, old_path=None, new_path=None, **kwargs) -> None β€” implements torrents_rename_file(). Returns None.
  • rename_folder(old_path=None, new_path=None, **kwargs) -> None β€” implements torrents_rename_folder(). Returns None.
  • resume(**kwargs) -> None β€” implements torrents_start(). Returns None. Resume = start, they're the same thing here 🫢
  • setComment(comment=None, **kwargs) -> None β€” implements torrents_set_comment(). Returns None. Yep, camelCase version exists too, legacy bestie πŸͺ
  • set_auto_management(enable=None, **kwargs) -> None β€” implements torrents_set_auto_management(). Returns None.
  • set_category(category=None, **kwargs) -> None β€” implements torrents_set_category(). Returns None.
  • set_comment(comment=None, **kwargs) -> None β€” implements torrents_set_comment(). Returns None. The snake_case twin of setComment. 🐍
  • set_download_limit(limit=None, **kwargs) -> None β€” implements torrents_set_download_limit(). Returns None.
  • set_download_path(download_path=None, **kwargs) -> None β€” implements torrents_set_download_path(). Returns None.
  • set_force_start(enable=None, **kwargs) -> None β€” implements torrents_set_force_start(). Returns None.
  • set_location(location=None, **kwargs) -> None β€” implements torrents_set_location(). Returns None. Move the whole thing somewhere new 🚚
  • set_save_path(save_path=None, **kwargs) -> None β€” implements torrents_set_save_path(). Returns None.
  • set_share_limits(ratio_limit=None, seeding_time_limit=None, inactive_seeding_time_limit=None, **kwargs) -> None β€” implements torrents_set_share_limits(). Returns None. Three separate limits, all optional, all yours. βš–οΈ
  • set_super_seeding(enable=None, **kwargs) -> None β€” implements torrents_set_super_seeding(). Returns None. Super seeding?? super slay 🦸
  • set_tags(tags=None, **kwargs) -> None β€” implements torrents_set_tags(). Returns None.
  • set_upload_limit(limit=None, **kwargs) -> None β€” implements torrents_set_upload_limit(). Returns None.
  • start(**kwargs) -> None β€” implements torrents_start(). Returns None. Go go go πŸ”₯
  • property state_enum: TorrentState β€” torrent state enum. The enum-ified state, no string guessing. 🌈
  • stop(**kwargs) -> None β€” implements torrents_stop(). Returns None.
  • sync_local() -> None β€” update local cache of torrent info. Returns None. Takes no kwargs, just does the thing. πŸ”„
  • toggle_first_last_piece_priority(**kwargs) -> None β€” implements torrents_toggle_first_last_piece_priority(). Returns None.
  • toggle_sequential_download(**kwargs) -> None β€” implements torrents_toggle_sequential_download(). Flip that sequential-download switch, bestie. πŸ”€

Return type: None πŸ’…

  • top_priority(**kwargs) -> None β€” Implements torrents_top_priority().
    • Return type: None
  • property trackers: TrackersList β€” Implements torrents_trackers().
  • property upload_limit: int β€” Implements torrents_upload_limit().
  • property webseeds: WebSeedsList β€” Implements torrents_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 β€” Implements torrents_categories().
  • create_category(name=None, save_path=None, download_path=None, enable_download_path=None, **kwargs) -> None β€” Implements torrents_create_category().
    • Return type: None
  • edit_category(name=None, save_path=None, download_path=None, enable_download_path=None, **kwargs) -> None β€” Implements torrents_edit_category().
    • Return type: None
  • remove_categories(categories=None, **kwargs) -> None β€” Implements torrents_remove_categories().
    • Return type: None

πŸ¦‹ 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 β€” Implements torrents_add_tags().
    • Return type: None
  • create_tags(tags=None, **kwargs) -> None β€” Implements torrents_create_tags().
    • Return type: None
  • delete_tags(tags=None, **kwargs) -> None β€” Implements torrents_delete_tags().
    • Return type: None
  • remove_tags(tags=None, torrent_hashes=None, **kwargs) -> None β€” Implements torrents_remove_tags().
    • Return type: None
  • set_tags(tags=None, torrent_hashes=None, **kwargs) -> None β€” Implements torrents_set_tags().
    • Return type: None
  • property tags: TagList β€” Implements torrents_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
  • transfer_download_limit(**kwargs) -> int β€” Retrieves download limit; 0 is unlimited.
    • Return type: int
  • transfer_info(**kwargs) -> TransferInfoDictionary β€” Retrieves the global transfer info found in qBittorrent status bar.
    • Return type: TransferInfoDictionary
  • 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
  • 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
  • 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
  • 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
  • transfer_speed_limits_mode(**kwargs) -> str β€” Returns 1 if alternative speed limits are currently enabled, 0 otherwise.
    • Return type: str
  • 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.
  • 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 as 2.8.4
  • Return type β€” bool
  • Returns β€” True or False for 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 as v4.4.0
  • Return type β€” bool
  • Returns β€” True or False for 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. 🫢

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