Author: Arvid Norberg, arvid@libtorrent.org

| libtorrent

# libtorrent python binding

Author: | Arvid Norberg, arvid@libtorrent.org
Version: | 1.2.9

Table of contents

- building
  - building using boost build (windows)
  - building using boost build (others)
- using libtorrent in python
- set_alert_notify
- Example

# building

Building the libtorrent python bindings will produce a shared library (DLL) which is a python module that can be imported in a python program.

## building using boost build (windows)

Download and install Visual C++ 2015 Build Tools

Download Boost libraries Extract it to c:/Libraries/boost_1_73_0 and create these environmental vars:

1. BOOST_BUILD_PATH: "c:/Libraries/boost_1_73_0/tools/build/"
2. BOOST_ROOT: "c:/Libraries/boost_1_73_0/"

Navigate to `BOOST_ROOT`, execute "bootstrap.bat" and add to the path "c:/Libraries/boost_1_73_0/"

Move the file `user-config.jam` from `%BOOST_BUILD_PATH%/example/` to `%BOOST_BUILD_PATH%/user-config.jam` and add this at the end:

    using msvc : 14.0 : : /std:c++11 ;
    using python : 3.5 : C:/Users/<UserName>/AppData/Local/Programs/Python/Python35 : C:/Users/<UserName>/AppData/Local/Programs/Python/Python35/include : C:/Users/<UserName>/AppData/Local/Programs/Python/Python35/libs ;

(change the python path for yours)

Navigate to bindings/python and execute::
  python setup.py build --bjam

Note: If you are using 64 bits python you should edit setup.py and add this to the b2 command: `address-model=64`

This will create the file libtorrent.pyd inside build/lib/ that contains the binding.

## building using boost build (others)

To set up your build environment, you need to add some settings to your `$BOOST_BUILD_PATH/user-config.jam`.

A similar line to this line should be in the file (could be another python version):

    #using python : 2.3 ;

Uncomment it and change it with the version of python you have installed or want to use. If you've installed python in a non-standard location, you have to add the prefix path used when you installed python as a second option. Like this:

    using python : 2.6 : /usr/bin/python2.6 : /usr/include/python2.6 : /usr/lib/python2.6 ;

The bindings require at least python version 2.2.

For more information on how to install and set up boost-build, see the building libtorrent section.

Once you have boost-build set up, you cd to the `bindings/python` directory and invoke `b2` with the appropriate settings. For the available build variants, see libtorrent build options.

For example:

    $ b2 stage_module stage_dependencies

This will produce a `libtorrent` python module in the current directory (file name extension depends on operating system). The libraries the python module depends on will be copied into `./dependencies`.

# using libtorrent in python

The python interface is nearly identical to the C++ interface. Please refer to the library reference. The main differences are:

asio::tcp::endpoint
  The endpoint type is represented as a tuple of a string (as the address) and an int for the port number. E.g. `("127.0.0.1", 6881)` represents the localhost port 6881.
lt::time_duration
  The time duration is represented as a number of seconds in a regular integer.

The following functions takes a reference to a container that is filled with entries by the function. The python equivalent of these functions instead returns a list of entries.

- torrent_handle::get_peer_info
- torrent_handle::file_progress
- torrent_handle::get_download_queue
- torrent_handle::piece_availability

`create_torrent::add_node()` takes two arguments, one string and one integer, instead of a pair. The string is the address and the integer is the port.

`session::apply_settings()` accepts a dictionary with keys matching the names of settings in settings_pack. When calling `apply_settings`, the dictionary does not need to have every settings set, keys that are not present are not updated.

To get a python dictionary of the settings, call `session::get_settings`.

Retrieving session statistics in Python is more convenient than that in C++. The statistics are stored as an array in `session_stats_alert`, which will be posted after calling `post_session_stats()` in the `session` object. In order to interpret the statistics array, in C++ it is required to call `session_stats_metrics()` to get the indices of these metrics, while in Python it can be done using `session_stats_alert.values["NAME_OF_METRIC"]`, where `NAME_OF_METRIC` is the name of a metric.

# set_alert_notify

The `set_alert_notify()` function is not compatible with python. Since it requires locking the GIL from within the libtorrent thread, to call the callback, it can cause a deadlock with the main thread.

Instead, use the python-specific `set_alert_fd()` which takes a file descriptor that will have 1 byte written to it to notify the client that there are new alerts to be popped.

The file descriptor should be set to non-blocking mode. If writing to the file/sending to the socket blocks, libtorrent's internal thread will stall.

This can be used with `socket.socketpair()`, for example. The file descriptor is what `fileno()` returns on a socket.

# Example

For an example python program, see `client.py` in the `bindings/python` directory.

A very simple example usage of the module would be something like this:

    import libtorrent as lt
    import time
    import sys

    ses = lt.session({'listen_interfaces': '0.0.0.0:6881'})

    info = lt.torrent_info(sys.argv[1])
    h = ses.add_torrent({'ti': info, 'save_path': '.'})
    s = h.status()
    print('starting', s.name)

    while (not s.is_seeding):
        s = h.status()

        print('\r%.2f%% complete (down: %.1f kB/s up: %.1f kB/s peers: %d) %s' % (
            s.progress * 100, s.download_rate / 1000, s.upload_rate / 1000,
            s.num_peers, s.state), end=' ')

        alerts = ses.pop_alerts()
        for a in alerts:
            if a.category() & lt.alert.category_t.error_notification:
                print(a)

        sys.stdout.flush()

        time.sleep(1)

    print(h.status().name, 'complete')