Changelog

v0.3.*

v0.3.4 - 2025-10-06

Bugfix

  • Fix serialization of hashes in print mode, which now prints the hex-encoded version everywhere

  • Add humanize to required deps

v0.3.3 - 2025-09-30

Bugfix

Fixed the cli torrent make command, which was using the old files and creator convenience fields.

v0.3.2 - 2025-08-21

Bugfix

#9 - Fixed incorrectly finding start of piece using modulo rather than subtraction, which could cause duplicate/incorrect ranges in the cae that e.g. multiple files that were exactly piece length were at the start of a torrent.

v0.3.1 - 2025-08-04

#8

Features By the time we have piece ranges, we don’t know about the torrent info.name field anymore, so we can’t construct URLs accurately.

Give that responsibility to the relevant piece range classes, giving them a webseed_url method that can be used to get the full url to request from some url that’s used as a webseed.

so e.g. for a multi-file torrent named my_torrent with a file a.exe, a webseed given as https://example.com/data/ should have the file stored at https://example.com/data/my_torrent/a.exe

Bugfix

this also fixes v1-only single file torrents (a rare and discouraged case) which improperly added the metadata to the files list, rather than just having name and length.

v0.3.0 - 2025-07-28

#6 Add ability to get v1 and v2 byte ranges to validate partial data against.

The behavior differs somewhat significantly between v1 and v2, so we made separate implementations for both

  • v1: Torrent.v1_piece_range() a piece may correspond to a range within a single file or across several, and may include padfiles that shouldn’t really “exist” on a filesystem

  • v2: Torrent.v2_piece_range() much simpler, a file either has a single root hash or a set of hashes from a lower level of the merkle tree, both are computed identically. pieces are always either a whole file or a part of a single file.

These correspond to the models returned, which both have a validate_data() method:

So we have two methods to get v1 and v2 ranges, which return a PieceRange object that can validate data passed to validate_data

so e.g. if we have a v1 torrent of 5 10KiB files of all zeros, and a piece size of 32 KiB, we might do somethign like this

piece_range = torrent.v1_piece_range(0)
piece_range.validate_data([bytes(10), bytes(10), bytes(10), bytes(2)])

and v2 torrents work at the block level, as they usually do, so if we had a single-file v2 torrent with an empty 64 KiB file with a piece size of 64KiB, we would do

piece_range = torrent.v2_piece_range('filename')
piece_range.validate_data([bytes(16 * KiB) for _ in range(4)])

Breaking

  • changed the behavior of v2 piece layers dict to match v1 pieces: when in memory, we split up the pieces into a list of hashes, rather than one bigass bytestring, and then split again on serialization.

v0.2.*

v0.2.1 - 2025-07-27

bugfix

  • raise error in clean_files when files are missing or misspecified,

  • rather than allowing to fall through to the generation process.

perf:

  • cache computed infohashes rather than computing fresh each time.

v0.2.0 - 2025-07-27

Version deployed with initial integration with sciop

breaking:

  • InfoDictV1.v1_infohash and InfoDictV2.v2_infohash now return hex-encoded strings rather than bytes, because they are more commonly used than the bytes representation

  • Remove async file i/o while hashing, see perf.

perf:

  • Added parallel hashing codepath for cpu == 1 because making pools takes forever when making many small torrents, e.g. in testing

  • hashing switched from async to sync because async was significantly slower for unclear benefit

internal changes:

  • n_processors defaults to 1 rather than ncpus until perf problems can be resolved

deps:

  • remove anyio

  • remove nest-asyncio

v0.1.2 - 2025-07-25

quick iterations while integrating with sciop

  • Add convenience properties for accessing trackers and files

  • Allow trackerless torrents

v0.1.1 - 2025-07-25

Preparing to swap in for sciop, where it will get real field testing. Basic creation and validation systems work and have been validated against a corpus of torrents in the wild.

Changelog will now actually contain meaningful changes, since the package is now considered out of experimental phase and in beta.

v0.0.*

v0.0.2 - 2025-05-24

  • Bugfix: force absolute paths in path_roots

  • Docs: exist

v0.0.1 - Start of package

Hello world, we have torrent models and hashing :)