Metadata-Version: 2.1
Name: qbittorrent-api
Version: 6.0.0
Summary: Python client for qBittorrent v4.1+ Web API
Home-page: https://github.com/rmartin16/qbittorrent-api
Author: Russell Martin
License: GPL-3
Description: qBittorrent Web API Client
        ================================
        Python client implementation for qBittorrent Web API. Supports qBittorrent v4.1.0+ (i.e. Web API v2.0+).
        
          * [Features](#features)
          * [Installation](#installation)
          * [Getting Started](#getting-started)
          * [Behavior & Configuration](#behavior--configuration)
          * [Performance](#performance)
          * [API Documentation](#api-documentation)
          * [Direct API Endpoint Access](#direct-api-endpoint-access)
          * [Interaction Layer Usage](#interaction-layer-usage)
          * [Interaction Layer Notes](#interaction-layer-notes)
          * [Interaction Layer Details](#interaction-layer-details)
          * [Exceptions](#exceptions)
          
        The full qBittorrent Web API specification is documented on their [wiki](https://github.com/qbittorrent/qBittorrent/wiki/Web-API-Documentation).
        
        Features
        ------------
        * The entire qBittorent Web API is implemented.
        * qBittorrent version checking for an endpoint's existence/features is automatically handled.
        * All Python versions are supported.
        * If the authentication cookie expires, a new one is automatically requested in line with any API call.
        
        Installation
        ------------
        * Install via pip from [PyPI](https://pypi.org/project/qbittorrent-api/):
          * `pip install qbittorrent-api`
        * Install specific release:
          * `pip install git+https://github.com/rmartin16/qbittorrent-api.git@v0.3.2#egg=qbittorrent-api`
        * Install direct from master:
          * `pip install git+https://github.com/rmartin16/qbittorrent-api.git#egg=qbittorrent-api`
        * Ensure urllib3, requests, and attrdict are installed. (These are installed automatically using the methods above.)
        * Enable WebUI in qBittorrent: Tools -> Preferences -> Web UI
        * If the Web API will be exposed to the Internet (i.e. made available outside your network), please [do it properly](https://github.com/qbittorrent/qBittorrent/wiki/Linux-WebUI-HTTPS-with-Let's-Encrypt-certificates-and-NGINX-SSL-reverse-proxy).
        
        Getting Started
        ---------------
        ```python
        import qbittorrentapi
        
        # instantiate a Client using the appropriate WebUI configuration
        qbt_client = qbittorrentapi.Client(host='localhost:8080', username='admin', password='adminadmin')
        
        # the Client will automatically acquire/maintain a logged in state in line with any request.
        # therefore, this is not necessary; however, you many want to test the provided login credentials.
        try:
            qbt_client.auth_log_in()
        except qbittorrentapi.LoginFailed as e:
            print(e)
        
        # 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})')
        
        # pause all torrents
        qbt_client.torrents.pause.all()
        ```
        
        Behavior & Configuration
        -------------
        * **WARNING**: Using an untrusted (e.g. self-signed) certificate for HTTPS WebUI
          * Instantiate Client with `VERIFY_WEBUI_CERTIFICATE=False` or set environment variable `PYTHON_QBITTORRENTAPI_DO_NOT_VERIFY_WEBUI_CERTIFICATE` to a non-null value.
          * Failure to do this for will cause connections to qBittorrent to fail.
          * As a word of caution, doing this actually does turn off certificate verification. Therefore, for instance, potential man-in-the-middle attacks will not be detected and reported (since the error is suppressed). However, the connection will remain encrypted.
        * Host, Username and password Defaults
          * These can be provided when instantiating Client or calling `qbt_client.auth_log_in(username='...', password='...')`.
          * Alternatively, set environment variables `PYTHON_QBITTORRENTAPI_HOST`, `PYTHON_QBITTORRENTAPI_USERNAME` and `PYTHON_QBITTORRENTAPI_PASSWORD`.
        * API Endpoints Not Yet Implemented in the qBittorrent Host
          * By default, if a call is made to endpoint that doesn't yet exist on the 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 UnimplementedError instead, instantiate Client with `RAISE_UNIMPLEMENTEDERROR_FOR_UNIMPLEMENTED_API_ENDPOINTS=True`.
        * 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) ```
        
        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).
        
        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.
        ```python
        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.
        ```python
        qbt_client.torrents.files(hash='...', SIMPLE_RESPONSES=True)
        ```
        
        API Documentation
        ---------------
        The Client's methods all document their own description, expected arguments, possible exceptions, and return value.
        
        For best results, use the "most primitive" form of the API call. So, `qbt_client.torrents_pause` instead of `qbt_client.torrents.pause`.
        
        ```python
        help(qbt_client.torrents_add)
        help(qbt_client.torrents_add_trackers)
        ```
        
        Direct API Endpoint Access
        --------------------------
        The API is separated in to eight namespaces for the API endpoints:
        
        * Authentication (auth)
        * Application (app)
        * Log (log)
        * Sync (sync)
        * Transfer (transfer)
        * Torrent Management (torrents)
        * RSS (rss)
        * Search (search)
        
        To use this package to directly access those endpoints:
        
        ```python
        response = qbt_client.<name>_<api method>(<arguments>)
        ```
        Replace `<name>` with one of the eight namespaces (from within the parentheses) above and `<api method>` with a relevant endpoint.
        
        For instance:
        ```python
        torrent_list = qbt_client.torrents_info(status_filter='active')
        ```
        
        The responses from the API calls are strings (e.g. app/version) or an extended Dictionary or List object (e.g. torrents/trackers).
        
        Each namespace endpoint's method name is [PEP8](https://www.python.org/dev/peps/pep-0008/)-ified. However, they are all aliased to the endpoint's name as implemented in qBittorrent's Web API. So, for example, `qbt_client.app_web_api_version()` and `qbt_client.app_webapiVersion()` are equivalent. This is also true for the API methods' arguments; so, `qbt_client.torrents_add(urls='...', save_path='/torrents')` and `qbt_client.torrents_add(urls='...', savepath='/torrents')` are equivalent. This is intended to allow use of this Client only depending on qBittorrent's own [Web API documentation](https://github.com/qbittorrent/qBittorrent/wiki/Web-API-Documentation).
        
        
        Interaction Layer Usage
        --------------------------------------
        The package also contains more robust interfaces to the API endpoints. For each of the eight namespaces, there is an interface to the relevant API endpoints. Of note, I created additional namespaces for torrent categories and torrent tags.
        
        An example for the Application namespace:
        ```Python
        ver = qbt_client.app.version
        api_ver = qbt_client.app.api_web_version
        prefs = qbt_client.app.preferences
        is_dht_enabled = qbt_client.application.preferences.dht
        qbt_client.application.preferences = dict(dht=(not is_dht_enabled))
        ```
        
        For each namespace, all endpoints with a return value and no parameters are implemented as a property. All other endpoints are implemented as methods; some of the methods have extended usage as well.
        
        For example, the log/main endpoint has extended usage:
        ```python
        complete_log = qbt_client.log.main()
        normal_log = qbt_client.log.main.normal()
        warning_log = qbt_client.log.main.warning()
        critical_log = qbt_client.log.main.critical()
        ```
        The most extended namespace is Torrents.
        ```python
        # Gathering torrents
        torrent_list = qbt_client.torrents.info()
        torrent_list_active = qbt_client.torrents.info.active()
        torrent_list_active_partial = qbt_client.torrents.active(limit=100, offset=200)
        torrent_list_downloading = qbt_client.torrents.info.downloading()
        
        # Torrent looping
        for torrent in torrent_list:
          print(torrent.name)
        
        # Actions for multiple torrents
        qbt_client.torrents.pause(hashes=['...', '...'])
        qbt_client.torrents.recheck(hashes=['...', '...'])
        # or just do all torrent 
        qbt_client.torrents.pause.all()
        qbt_client.torrents.recheck.all()
        qbt_client.torrents.resume.all()
        ```
        
        Once you have a torrent, there's also a litany of interactions.
        ```python
        hash = torrent.info.hash  # as well the rest of the properties from torrents/info endpoint
        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.resume()
        torrent.pause()
        torrent.recheck()
        torrent.torrents_top_priority()
        torrent.set_location(location='/home/user/torrents/')
        torrent.set_category(category='video')
        ```
        
        Search extended usage.
        ```python
        search_job = qbt_client.search.start(pattern='Ubuntu', categories='all', plugins='all')
        while search_job.status()[0].status != 'Stopped':
          time.sleep(.1)
        print(search_job.results())
        search_job.delete()
        ```
        
        Interaction Layer Notes
        -----------------------
        * All endpoints are available with and without the endpoint's namespace attached.
          * So, `qbt_client.torrents.torrents_resume()` and `qbt_client.torrents.resume()` are the same.
          * As mentioned in direct API access `qbt_client.app.web_api_version` and `qbt_client.app.webapiVersion` are the same.
        * When invoking the API calls, you can use the parameters implemented in the python code or those specified in the API documentation.
          * So, `torrents_rename(hash='...', new_torrent_name="...")` and `torrents_rename(hash='...', name="...")` are the same.
        
        Interaction Layer Details
        -------------------------
        * Application
          * Properties
            * version
            * web_api_version
            * build_info
            * default_save_path
            * preferences (supports assignment)
          * Methods
            * shutdown
        * Log
          * Methods
            * main
              * Methods
                * info
                * normal
                * warning
                * critical
            * peers
        * Sync
          * Methods
            * maindata
              * Methods
                * delta
                * reset_rid
            * torrent_peers
        * Transfer
          * Properties
            * info
            * speed_limits_mode (supports assignment)
            * download_limit (supports assignment)
            * upload_limit (supports assignment)
          * Methods
            * set_download_limit
            * set_upload_limit
            * toggle_speed_limits_mode
        * Torrents
          * Methods
            * Note: each of these "methods" supports the all() method
            * info
              * Methods
                * downloading
                * completed
                * paused
                * active
                * inactive
                * resumed
            * resume
            * pause
            * delete
            * recheck
            * reannounce
            * increase_priority
            * decrease_priority
            * top_priority
            * bottom_priority
            * download_limit
            * set_download_limit
            * set_share_limits
            * upload_limit
            * set_upload_limit
            * set_location
            * set_category
            * set_auto_management
            * toggle_sequential_download
            * toggle_first_last_piece_priority
            * set_force_start
            * set_super_seeding
        * Torrent
          * Properties
            * info
            * properties
            * trackers
            * webseeds
            * files
            * piece_states
            * piece_hashes
            * download_limit (supports assignment)
            * upload_limit (supports assignment)
          * Methods
            * add_trackers
            * edit_tracker
            * remove_trackers
            * file_priority
            * filePrio
            * rename
            * set_location
            * set_category
            * set_auto_management
            * set_force_feeding
            * set_super_seeding
            * AND all the Torrents methods above
        * Torrent Categories
          * Properties
            * categories
          * Methods
            * create_category
            * edit_category
            * remove_categories
        * Torrent Tags
          * Properties
            * tags
          * Methods
            * add_tags
            * remove_tags
            * create_tags
            * delete_tags
        * RSS
          * Properties
            * rules
          * Methods
            * add_folder
            * add_feed
            * remove_item
            * refresh_item
            * move_item
            * items
              * Methods
                * without_data
                * with_data
            * set_rule
            * rename_rule
            * remove_rule
        * Search
          * Properties
            * plugins
          * Methods
            * start
            * stop
            * status
            * results
            * delete
            * categories
            * install_plugin
            * uninstall_plugin
            * enable_plugin
            * update_plugins
        * Seach Job
          * Methods
            * stop
            * results
            * status
            * delete
        
        Exceptions
        ----------
        To see the exceptions an endpoint can raise, use `help(qbt_client.<namespace>_<method>)`.
        
        For example:
        ```
        >>> import qbittorrentapi
        >>> help(qbittorrentapi.Client.torrents_add)
        
        Help on function torrents_add in module qbittorrentapi.torrents:
        
        torrents_add(self, 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, **kwargs)
            Add one or more torrents by URLs and/or torrent files.
            
            Exceptions:
                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
            
            :param urls: List of URLs (http://, https://, magnet: and bc://bt/)
            :param torrent_files: list of torrent files
            :param save_path: location to save the torrent data
            :param cookie: cookie to retrieve torrents by URL
            :param category: category to assign to torrent(s)
            :param is_skip_checking: skip hash checking
            :param is_paused: True to start torrent(s) paused
            :param is_root_folder: True or False to create root folder
            :param rename: new name for torrent(s)
            :param upload_limit: upload limit in bytes/second
            :param download_limit: download limit in bytes/second
            :param use_auto_torrent_management: True or False to use automatic torrent management
            :param is_sequential_download: True or False for sequential download
            :param is_first_last_piece_priority: True or False for first and last piece download priority
            :return: "Ok." for success and ""Fails." for failure
        ```
        
        
        ```python
        class APIError(Exception):
            """
            Base error for all exceptions from this Client.
            """
            pass
        
        
        class FileError(IOError, APIError):
            """
            Base class for all exceptions for file handling.
            """
            pass
        
        
        class TorrentFileError(FileError):
            """
            Base class for all exceptions for torrent files.
            """
            pass
        
        
        class TorrentFileNotFoundError(TorrentFileError):
            """
            Specified torrent file does not appear to exist.
            """
            pass
        
        
        class TorrentFilePermissionError(TorrentFileError):
            """
            Permission was denied to read the specified torrent file.
            """
            pass
        
        
        class APIConnectionError(RequestException, APIError):
            """
            Base class for all communications errors including HTTP errors.
            """
            pass
        
        
        class LoginFailed(APIConnectionError):
            """
            This can technically be raised with any request since log in may be attempted for any request and could fail.
            """
            pass
        
        
        class HTTPError(APIConnectionError):
            """
            Base error for all HTTP errors. All errors following a successful connection to qBittorrent are returned as HTTP statuses.
            """
            pass
        
        
        class HTTP4XXError(HTTPError):
            """
            Base error for all HTTP 4XX statuses.
            """
            pass
        
        
        class HTTP5XXError(HTTPError):
            """
            Base error for all HTTP 5XX statuses.
            """
            pass
        
        
        class HTTP400Error(HTTP4XXError):
            pass
        
        
        class HTTP401Error(HTTP4XXError):
            pass
        
        
        class HTTP403Error(HTTP4XXError):
            pass
        
        
        class HTTP404Error(HTTP4XXError):
            pass
        
        
        class HTTP409Error(HTTP4XXError):
            pass
        
        
        class HTTP415Error(HTTP4XXError):
            pass
        
        
        class HTTP500Error(HTTP5XXError):
            pass
        
        
        class MissingRequiredParameters400Error(HTTP400Error):
            """
            Endpoint call is missing one or more required parameters.
            """
            pass
        
        
        class InvalidRequest400Error(HTTP400Error):
            """
            One or more endpoint arguments are malformed.
            """
            pass
        
        
        class Unauthorized401Error(HTTP401Error):
            """
            Primarily reserved for XSS and host header issues.
            """
            pass
        
        
        class Forbidden403Error(HTTP403Error):
            """
            Not logged in, IP has been banned, or calling an API method that isn't public.
            """
            pass
        
        
        class NotFound404Error(HTTP404Error):
            """
            This should mean qBittorrent couldn't find a torrent for the torrent hash.
            It is also possible this means the endpoint doesn't exist in qBittorrent...but that also means this Client has a bug.
            """
            pass
        
        
        class Conflict409Error(HTTP409Error):
            """
            Returned if arguments don't make sense specific to the endpoint.
            """
            pass
        
        
        class UnsupportedMediaType415Error(HTTP415Error):
            """
            torrents/add endpoint will return this for invalid URL(s) or files.
            """
            pass
        
        
        class InternalServerError500Error(HTTP500Error):
            """
            Returned if qBittorent craps on itself while processing the request...
            """
            pass
        ```
        
Keywords: qbittorrent api
Platform: UNKNOWN
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 2.6
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
Classifier: Topic :: Communications :: File Sharing
Classifier: Topic :: Utilities
Description-Content-Type: text/markdown
