Skip to main content

yap_torrent Transmission RPC

A yap_torrent plugin that exposes a Transmission RPC compatible server, so existing Transmission remote clients (Transmission Remote GUI, transmission-remote, the transmission-rpc Python library, mobile remotes, …) can drive yap_torrent — and a browser UI, served on the same port, that is itself one of those clients.

Installation

pip install yap_torrent_transmission_rpc

Or from a checkout, for development:

pip install -e plugins/transmission_rpc

The plugin is discovered automatically through the yap_torrent.plugins entry point. Disable it by adding yap_torrent_transmission_rpc to disabled_plugins in config.json.

Configuration

Add a yap_torrent_transmission_rpc block to config.json:

{
  "yap_torrent_transmission_rpc": {
    "host": "0.0.0.0",
    "port": 9091,
    "path": "/transmission/rpc",
    "web_enabled": true,
    "web_path": "/transmission/web",
    "username": null,
    "password": null
  }
}
  • host / port — where the server binds (Transmission's default port is 9091).
  • path — RPC endpoint path (Transmission's default is /transmission/rpc).
  • web_enabled — serve the bundled browser UI. Turning it off leaves the RPC untouched.
  • web_path — where the UI is mounted. / redirects to it.
  • username / passwordreserved for a future HTTP Basic auth implementation. They are read but not enforced yet; the endpoint is currently unauthenticated.

Point a remote at http://<host>:9091/transmission/rpc, or a browser at http://<host>:9091/.

Web interface

The UI lives in src/yap_torrent_transmission_rpc/html/ and is a pure RPC client — it has no endpoint of its own and reads nothing out of the ECS. Everything it shows comes from torrent-get / session-get, and everything it does goes out as a spec method, which is why it lives here rather than in a plugin of its own: a field added for a Transmission remote is a field the browser can show, and a torrent becomes JSON in exactly one place (mapping.py). It replaces the old yap_torrent_web plugin, which derived the same values a second time behind its own /api/* routes.

Sharing the RPC's port is what keeps it same-origin, so there is no CORS to configure and the CSRF handshake below works from the page unchanged. The endpoint is substituted into the page at serve time (the rpc-path meta tag), so a changed path needs no edit to the script.

It covers: the torrent list with live rates, status and ETA, refreshed every 2s; add by magnet, URL or .torrent upload; start / stop / verify / reannounce; remove, with or without the data; queue reordering; per-file wanted flags and priorities; labels; tracker state; and a session settings panel. Multi-select with ctrl/cmd-click applies an action to every selected torrent.

The settings panel says plainly which values do nothing yet, because session-set answers success for all of them: the peer port and DHT are start-up-only (saved, but the running client keeps its values), and the speed, queue, ratio and peer limits are stored and reported back but enforced by nothing.

CSRF handshake

Per the spec, the server issues an X-Transmission-Session-Id. The first request (or one with a stale id) receives an HTTP 409 carrying the current id in its headers; well-behaved clients transparently retry with it. This is handled automatically for real clients.

Supported methods

This targets the legacy Transmission RPC protocol — method/arguments/tag with kebab-case names — which is what existing remotes and the transmission-rpc Python client speak. Transmission 4.1 deprecates it in favour of JSON-RPC 2.0 with snake_case names (rpc_version 19); that is a separate surface, not a newer version of this one. The supported range is declared by RPC_VERSION_MIN_SUPPORTED / RPC_VERSION_MAX_SUPPORTED in methods.py (14–17, semver 5.3.0 — the semver must track the max per the spec's version table, because clients gate features on it).

Implemented: torrent-add, torrent-remove, torrent-start, torrent-start-now, torrent-stop, torrent-verify, torrent-get, torrent-set, torrent-reannounce, queue-move-top, queue-move-up, queue-move-down, queue-move-bottom, session-get, session-set, session-stats, free-space, port-test.

torrent-set — and torrent-add, which takes the same arguments — applies labels, files-wanted, files-unwanted, priority-high|normal|low and queuePosition, and stores downloadLimit, uploadLimit, honorsSessionLimits, seedRatioLimit, seedRatioMode, peer-limit and bandwidthPriority without enforcing them: core has no bandwidth limiting or ratio tracking, so the values round-trip and core logs a warning naming each one. location and the deprecated tracker edits are ignored.

session-set writes through to core's config (which persists to config.json). Speed limits, queue sizes and the blocklist keys are stored but not enforced, and core warns on each change.

The speed model is mostly the plugin's. Core holds one number per direction where 0 means no limit — no separate on/off flag, and no second "alternative" pair. The plugin translates:

  • speed-limit-down / speed-limit-down-enabled (and the -up pair) fold into core's single number. Switching a limit off writes 0; the number you typed is remembered in the plugin's config section, so it is still in the box afterwards and comes back when you switch the limit on again. A number sent without the flag does not switch a disabled limit on — that is what the flag is for — it is only remembered.
  • alt-speed-down / alt-speed-up / alt-speed-enabled (turtle mode) never reach core at all.

Both the turtle values and the remembered numbers live in SpeedSettingsEC, a singleton component in the shared ECS — one instance for the whole app, reachable with get_speed_settings(env), so anything else that wants to know whether turtle mode is on reads the same object. It is runtime state: seeded from the yap_torrent_transmission_rpc section of config.json at startup and never written back, because turning turtle mode on is something you do now, not something the next run should inherit. The only speed value that outlives the process is the one core already keeps — the limit actually in force.

Once core enforces limits, enabling turtle mode should push the alt pair into core's speed_limit_* and restore the normal pair on the way out — see the SpeedSettingsEC TODO.

Every other spec method is recognised but returns an explanatory error string (it is not treated as an unknown method). See UNIMPLEMENTED in methods.py for the list and the notes on what each one needs. torrent-add accepts a magnet link or .torrent path/URL via the filename field, or base64 .torrent content via metainfo.

torrent-get supports both format: "objects" and format: "table", and reports live transfer rates and ETA, the added/started/done/activity dates, queue position, labels, exact per-file bytesCompleted with each file's wanted flag and priority, per-tracker announce state, and tracker errors via error/errorString. percentDone, sizeWhenDone and leftUntilDone are relative to the files the user wants, per tr_stat; percentComplete is of the whole torrent. Every documented field is answered — absent keys are not safe, since transmission-rpc reads them as self.fields[name] and raises KeyError. Still placeholder: the peers detail list, availability, secondsDownloading / secondsSeeding, and the seed-idle fields.

Tests

# only the test runner is needed; yap_torrent / angelovich.core are imported
# from source by conftest.py (no package install required)
pip install pytest pytest-aiohttp
pytest plugins/transmission_rpc          # test_rpc.py: the methods; test_web_ui.py: the UI routes

# manual smoke test against a running instance:
python plugins/transmission_rpc/scripts/manual_test.py --url http://127.0.0.1:9091/transmission/rpc

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

yap_torrent_transmission_rpc-0.1.1.tar.gz (33.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

yap_torrent_transmission_rpc-0.1.1-py3-none-any.whl (38.5 kB view details)

Uploaded Python 3

File details

Details for the file yap_torrent_transmission_rpc-0.1.1.tar.gz.

File metadata

File hashes

Hashes for yap_torrent_transmission_rpc-0.1.1.tar.gz
Algorithm Hash digest
SHA256 997c41f5cc34c8da49baa2ba340ebfd7b38384cfea6746381d3325feabf5fe1f
MD5 64dcd97cf1537772bcb1d897ba80970b
BLAKE2b-256 2d033c0cb85b23d1a0a630f28e1c55a9768858f675c4612c0c42ee1182cc76d0

See more details on using hashes here.

Provenance

The following attestation bundles were made for yap_torrent_transmission_rpc-0.1.1.tar.gz:

Publisher: python-publish-plugins-transmission-rpc.yml on Angel777d/yap_torrent

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file yap_torrent_transmission_rpc-0.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for yap_torrent_transmission_rpc-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 5f93b4b8465347e9637f8ed2ab4a385fb88d8f96ab0fb144fb97b4e14575b534
MD5 eeb8ef713afb64624bf51e00c140e7db
BLAKE2b-256 d6a5f670c6da317c7e0ac797c5a93e34937db9e32475ba8c346e58953b17f389

See more details on using hashes here.

Provenance

The following attestation bundles were made for yap_torrent_transmission_rpc-0.1.1-py3-none-any.whl:

Publisher: python-publish-plugins-transmission-rpc.yml on Angel777d/yap_torrent

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.3.0

2 files

0.1.2

2 files

This release

0.1.1 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page