Skip to content

Commit

Permalink
Add docs for async support
Browse files Browse the repository at this point in the history
  • Loading branch information
rmartin16 committed Dec 6, 2024
1 parent b842bea commit 1752e0d
Show file tree
Hide file tree
Showing 21 changed files with 70 additions and 45 deletions.
2 changes: 1 addition & 1 deletion docs/source/api.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
API Reference
================================
=============

.. toctree::
:maxdepth: 2
Expand Down
2 changes: 1 addition & 1 deletion docs/source/apidoc/app.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Application
================================
===========

.. autoclass:: qbittorrentapi.app.AppAPIMixIn
:members:
Expand Down
2 changes: 1 addition & 1 deletion docs/source/apidoc/attrdict.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
AttrDict (internal)
================================
===================

Copyright (c) 2013 Brendan Curran-Johnson

Expand Down
2 changes: 1 addition & 1 deletion docs/source/apidoc/auth.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Authentication
================================
==============

.. autoclass:: qbittorrentapi.auth.AuthAPIMixIn
:members:
Expand Down
2 changes: 1 addition & 1 deletion docs/source/apidoc/client.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Client
================================
======

.. autoclass:: qbittorrentapi.client.Client
:members:
Expand Down
2 changes: 1 addition & 1 deletion docs/source/apidoc/definitions.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Definitions
================================
===========

.. automodule:: qbittorrentapi.definitions
:members:
Expand Down
2 changes: 1 addition & 1 deletion docs/source/apidoc/log.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Log
================================
===

.. autoclass:: qbittorrentapi.log.LogAPIMixIn
:members:
Expand Down
2 changes: 1 addition & 1 deletion docs/source/apidoc/request.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Request (internal)
================================
==================

.. automodule:: qbittorrentapi.request
:members:
Expand Down
2 changes: 1 addition & 1 deletion docs/source/apidoc/rss.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
RSS
================================
====

.. autoclass:: qbittorrentapi.rss.RSSAPIMixIn
:members:
Expand Down
2 changes: 1 addition & 1 deletion docs/source/apidoc/search.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Search
================================
======

.. autoclass:: qbittorrentapi.search.SearchAPIMixIn
:members:
Expand Down
2 changes: 1 addition & 1 deletion docs/source/apidoc/sync.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Sync
================================
====

.. autoclass:: qbittorrentapi.sync.SyncAPIMixIn
:members:
Expand Down
2 changes: 1 addition & 1 deletion docs/source/apidoc/torrentcreator.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Torrent Creator
================================
===============

.. autoclass:: qbittorrentapi.torrentcreator.TorrentCreatorAPIMixIn
:members:
Expand Down
2 changes: 1 addition & 1 deletion docs/source/apidoc/torrents.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Torrents
================================
========

.. autoclass:: qbittorrentapi.torrents.TorrentsAPIMixIn
:members:
Expand Down
2 changes: 1 addition & 1 deletion docs/source/apidoc/transfer.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Transfer
================================
========

.. autoclass:: qbittorrentapi.transfer.TransferAPIMixIn
:members:
Expand Down
2 changes: 1 addition & 1 deletion docs/source/apidoc/version.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Version
================================
=======

.. autoclass:: qbittorrentapi._version_support.Version
:members:
Expand Down
33 changes: 33 additions & 0 deletions docs/source/async.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
Async Support
=============

``qbittorrent-api`` 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.

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.

.. code:: python
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:

.. code:: python
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()))
6 changes: 3 additions & 3 deletions docs/source/behavior&configuration.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Behavior & Configuration
================================
========================

Host, Username and Password
***************************
Expand Down Expand Up @@ -140,8 +140,8 @@ qBittorrent Version Checking
qbt_client = Client(..., RAISE_ERROR_FOR_UNSUPPORTED_QBITTORRENT_VERSIONS=True)
* Additionally, :class:`~qbittorrentapi._version_support.Version` can be used for manual introspection of
the versions.
* Additionally, :class:`~qbittorrentapi._version_support.Version` can be used for manual
introspection of the versions.
.. code:: python
Expand Down
3 changes: 2 additions & 1 deletion docs/source/index.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
qBittorrent Web API Client
================================
==========================

.. include:: introduction.rst

Expand All @@ -9,6 +9,7 @@ qBittorrent Web API Client

Introduction <introduction.rst>
Behavior & Configuration <behavior&configuration.rst>
Async Support <async.rst>
Performance <performance.rst>
Exceptions <exceptions.rst>
API Reference <api.rst>
27 changes: 6 additions & 21 deletions docs/source/introduction.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Introduction
======================
============

.. |github ci| image:: https://img.shields.io/github/checks-status/rmartin16/qbittorrent-api/main?style=flat-square
:target: https://github.com/rmartin16/qbittorrent-api/actions?query=branch%3Amain
Expand All @@ -22,7 +22,7 @@ Python client implementation for qBittorrent Web API.
Currently supports qBittorrent `v5.0.2 <https://github.com/qbittorrent/qBittorrent/releases/tag/release-5.0.2>`_ (Web API v2.11.2) released on Nov 17, 2024.

Features
------------
--------
- The entire qBittorrent `Web API <https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-4.1)>`_ is implemented.
- qBittorrent version checking for an endpoint's existence/features is automatically handled.
- If the authentication cookie expires, a new one is automatically requested in line with any API call.
Expand Down Expand Up @@ -122,7 +122,8 @@ Each Web API endpoint is implemented one-to-one as a method of the instantiated
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.
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.

.. code:: python
Expand All @@ -137,7 +138,8 @@ However, a more robust interface to the endpoints is available via each namespac
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.
Finally, some of the objects returned by the client support methods of their own. This is
most pronounced for torrents themselves.

.. code:: python
Expand All @@ -148,20 +150,3 @@ Finally, some of the objects returned by the client support methods of their own
torrent.set_location(location='/home/user/torrents/')
torrent.reannounce()
torrent.upload_limit = -1
asyncio support
---------------

Although there isn't direct support for asyncio, it is easy enough to make it work. The process is documented `here <https://github.com/rmartin16/qbittorrent-api/issues/404#issuecomment-1889667210>`_.

Here's an example:

.. code:: python
client = qbittorrentapi.Client()
async def main():
for t in await asyncio.to_thread(client.torrents_info, category="uploaded"):
print(t.name)
asyncio.run(main())
14 changes: 10 additions & 4 deletions docs/source/performance.rst
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
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).
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).

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.
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.

This client can be configured to always return only the simple JSON if desired. Simply set ``SIMPLE_RESPONSES=True`` when instantiating the client.
This client can be configured to always return only the simple JSON if desired. Simply
set ``SIMPLE_RESPONSES=True`` when instantiating the client.

.. code:: python
Expand All @@ -16,7 +21,8 @@ This client can be configured to always return only the simple JSON if desired.
SIMPLE_RESPONSES=True,
)
Alternatively, ``SIMPLE_RESPONSES`` can be set to ``True`` to return the simple JSON only for an individual method call.
Alternatively, ``SIMPLE_RESPONSES`` can be set to ``True`` to return the simple JSON
only for an individual method call.

.. code:: python
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ dependencies = [
dev = [
"build ==1.2.2.post1",
"coverage[toml] ==7.6.8",
"furo ==2024.8.6",
"mypy ==1.13.0",
"pre-commit ==4.0.1",
"pytest ==8.3.3",
Expand All @@ -49,6 +48,7 @@ dev = [

docs = [
# building docs requires Python >3.10
"furo ==2024.8.6",
"sphinx ==8.1.3",
"sphinx-autobuild ==2024.10.3",
"sphinx-copybutton ==0.5.2",
Expand Down

0 comments on commit 1752e0d

Please sign in to comment.