Usage
This guide explains how to use aiobtclientapi.
Basics
First, you need to create an instance of one of the APIBase
subclasses.
api_dg = aiobtclientapi.DelugeAPI("AzureDiamond:hunter2@localhost:1234")
api_qb = aiobtclientapi.QbittorrentAPI("AzureDiamond:hunter2@localhost:1234")
api_rt = aiobtclientapi.RtorrentAPI("path/to/rpc.socket")
api_tm = aiobtclientapi.TransmissionAPI("AzureDiamond:hunter2@localhost:1234")
You can also pick a subclass by client
name. client_names() returns a sorted sequence of valid
client names.
client_name = "rtorrent"
url = "path/to/rpc.socket"
api = aiobtclientapi.api(client_name, url)
API URLs
Most clients accept URLs like [USERNAME:PASSWORD@]HOST[:PORT].
Below are the exact URL formats for each client. Uppercase words are
placeholders and square brackets ([]) mark optional parts.
- Deluge
[USERNAME:PASSWORD@]HOST[:PORT]- qBittorrent
[http[s]://][USERNAME:PASSWORD@]HOST[:PORT]- rTorrent
[scgi://]HOST[:PORT][file://]SOCKET_PATHhttp[s]://[USERNAME:PASSWORD@]HOST[:PORT][/PATH]- Transmission
[http[s]://][USERNAME:PASSWORD@]HOST[:PORT][/PATH]
API Methods
Methods that can operate on multiple torrents always return
Response instances and don’t raise exceptions. This is
because the first operation might fail, but the remaining operations might still
succeed. You also don’t want to ignore the failed operation.
A Response provides both return values and Errors as attributes. It can also provide Warnings about non-fatal operations that didn’t happen as
planned. For example, you will get warned when you try to add a torrent that was
already added.
Return values are provided as one or more custom attributes that are documented by the API method.
See the Example Code below.
RPC Calls
You can call() arbtitrary RPC methods if there is no common API
method.
See the aiobtclientrpc documentation for details.
api = aiobtclientapi.TransmissionAPI("AzureDiamond:hunter2@localhost:1234")
info = await api.call("session-get")
info['arguments']['version']
>>> 3.21 (d34db33f)
Virtual Environment
There is a Makefile with a venv target that should set up everything you
need. You can undo this by simply deleting the venv directory.
$ make venv
$ source venv/bin/activate
Command Line Tool
aiobtclientapi comes with a very simple CLI command, btclient, that
allows you to call API methods and inspect the response. It is intended for
manual testing, not for productive use, but you may find it useful to start your
own project.
Example Usage
$ btclient qbittorrent 'AzureDiamond:hunter2@localhost' get_infohashes
>>> CALLING get_infohashes()
>>> Connection status changed: ConnectionStatus.connecting
>>> Connection status changed: ConnectionStatus.connected
>>> RESPONSE get_infohashes()
>>> * 8f6e8660855b91fc3facee3845d3dd9e8def32de
>>> * be7d32a5b47322efef9e9f42b1785c76bbefce7c
>>> Connection status changed: ConnectionStatus.disconnected
$ btclient qbittorrent 'AzureDiamond:hunter2@localhost' stop be7d32a5b47322efef9e9f42b1785c76bbefce7c
>>> CALLING stop('be7d32a5b47322efef9e9f42b1785c76bbefce7c')
>>> Connection status changed: ConnectionStatus.connecting
>>> Connection status changed: ConnectionStatus.connected
>>> RESPONSE stop('be7d32a5b47322efef9e9f42b1785c76bbefce7c')
>>> SUCCESS: True
>>> WARNINGS: []
>>> ERRORS: []
>>> TASKS: []
>>> STOPPED: ['be7d32a5b47322efef9e9f42b1785c76bbefce7c']
>>> ALREADY_STOPPED: []
>>> Connection status changed: ConnectionStatus.disconnected
$ btclient qbittorrent 'AzureDiamond:hunter2@localhost' call app/version
>>> CALLING call('app/version')
>>> Connection status changed: ConnectionStatus.connecting
>>> Connection status changed: ConnectionStatus.connected
>>> RESPONSE call('app/version')
>>> v4.4.3.1
>>> Connection status changed: ConnectionStatus.disconnected
Example Code
import asyncio
import aiobtclientapi
async def run():
# Create API instance
try:
api = aiobtclientapi.api(
name="qbittorrent",
url="localhost:5000",
username="AzureDiamond",
password="hunter2",
)
except aiobtclientapi.ValueError as e:
# Invalid client name or URL
print('Error:', e)
exit(1)
# Add torrents
response = await api.add(
"path/to/my.first.torrent",
"path/to/my.second.torrent",
"path/to/my.third.torrent",
stopped=True,
)
# success is only True if all of the torrents were added
if not response.success:
print("Something went wrong!")
# Handle errors
for error in response.errors:
print("Error:", error)
# Handle warnings
for warning in response.warnings:
print("Warning:", warning)
# Show which torrents were actually added
for infohash in response.added:
print("Added:", infohash)
# Get a list of existing torrents
try:
infohashes = await api.get_infohashes()
except aiobtclientapi.ConnectionError as e:
print("Unable to get infohashes:", e)
else:
print("Infohashes:")
for infohash in infohashes:
print(f" * {infohash}")
asyncio.run(run())