Creation API
btpc.creation
Create v1, v2, and hybrid torrent metainfo from filesystem payloads.
CancellationToken
class CancellationToken()
Request cooperative cancellation of creation or verification.
The same token may be passed to one or more operations. Calling cancel
is thread-safe; active operations stop at a core cancellation checkpoint and
raise CancelledError.
Examples:
>>> from btpc import CancellationToken
>>> token = CancellationToken()
>>> token.cancel()
>>> token.cancelled
True
cancel
cancel() -> None
Request cancellation.
cancelled
cancelled: bool
Return whether cancellation was requested.
CreateMetrics
class CreateMetrics(scan_ms: float, hash_ms: float, serialize_ms: float)
Record elapsed time for creation phases.
Attributes:
- scan_ms: Filesystem traversal time in milliseconds.
- hash_ms: Payload hashing time in milliseconds.
- serialize_ms: Canonical metainfo serialization time in milliseconds.
scan_ms
scan_ms: float
hash_ms
hash_ms: float
serialize_ms
serialize_ms: float
CreateOptions
class CreateOptions(mode: TorrentMode = TorrentMode.V1, piece_length: int | None = None, threads: int | None = None, trackers: Sequence[Sequence[str]] = (), web_seeds: Sequence[str] = (), nodes: Sequence[tuple[str, int]] = (), private: bool | None = None, source: str | None = None, comment: str | None = None, created_by: str | None = None, omit_created_by: bool = False, creation_date: int | None = None)
Configure deterministic torrent creation.
Tracker tiers, web seeds, and nodes are copied into immutable tuples when options are constructed. Later changes to caller-owned lists have no effect.
Attributes:
- mode: Protocol representation to create. The default is
TorrentMode.V1. - piece_length: Explicit piece length in bytes.
Noneselects the core’s deterministic automatic policy; v2 and hybrid values must satisfy BEP 52 constraints. - threads: Maximum hashing worker count.
Nonelets the core choose from available parallelism. - trackers: Tracker tiers as a sequence of URL-string sequences. Text is encoded as strict UTF-8 at the native boundary.
- web_seeds: Web seed URLs encoded as strict UTF-8.
- nodes: DHT bootstrap nodes as
(host, port)pairs. - private: Optional private flag stored in the info dictionary. Changing it changes the info hash.
- source: Optional source string stored in the info dictionary. Changing it changes the info hash.
- comment: Optional top-level comment. Changing it does not change the info hash.
- created_by: Explicit top-level creator text. When omitted, BTPC writes
btpc/<version>unlessomit_created_byis true. - omit_created_by: Suppress the default creator field. It cannot be combined
with an explicit
created_byvalue. - creation_date: Unix timestamp stored at the top level. Set a fixed value,
commonly
0, for reproducible output.
Examples:
>>> from btpc import CreateOptions, TorrentMode
>>> options = CreateOptions(
... mode=TorrentMode.HYBRID,
... piece_length=16_384,
... creation_date=0,
... threads=1,
... )
>>> options.mode is TorrentMode.HYBRID
True
mode
mode: TorrentMode
piece_length
piece_length: int | None
threads
threads: int | None
trackers
trackers: Sequence[Sequence[str]]
web_seeds
web_seeds: Sequence[str]
nodes
nodes: Sequence[tuple[str, int]]
private
private: bool | None
source
source: str | None
comment
comment: str | None
created_by
created_by: str | None
omit_created_by
omit_created_by: bool
creation_date
creation_date: int | None
CreateResult
class CreateResult
Expose generated metainfo, hashes, and metrics without eager copies.
metainfo
metainfo: Metainfo
Return cached metainfo for inspection, editing, magnets, or verification.
The generated metainfo is parsed once on first access without copying it through Python bytes or reading the payload again.
Examples:
>>> from pathlib import Path
>>> from tempfile import TemporaryDirectory
>>> from btpc import create_bytes
>>> with TemporaryDirectory() as directory:
... payload = Path(directory) / "hello.txt"
... _ = payload.write_bytes(b"hello torrent\n")
... result = create_bytes(payload)
... assert result.metainfo.verify(payload).is_valid
... assert result.metainfo is result.metainfo
bytes
bytes: bytes
Return generated metainfo bytes, copied on first request.
mode
mode: TorrentMode
Return the created protocol mode.
info_hash_v1
info_hash_v1: HashValue | None
Return the cached v1 info hash when applicable.
info_hash_v2
info_hash_v2: HashValue | None
Return the cached v2 info hash when applicable.
file_count
file_count: int
Return payload file count.
payload_bytes
payload_bytes: int
Return total payload bytes.
piece_count
piece_count: int
Return created piece count.
piece_length
piece_length: int
Return selected piece length.
piece_length_policy
piece_length_policy: str | None
Return automatic policy identifier for automatic selection.
metrics
metrics: CreateMetrics
Return cached phase timing metrics.
create
create(path: str | PathLike[str], destination: str | PathLike[str], *, options: CreateOptions | None = None, overwrite: bool = False, durable: bool = False, progress: Callable[[int, int, int], None] | None = None, cancellation: CancellationToken | None = None) -> CreateResult
Create canonical metainfo and atomically write a torrent file.
The destination is written through a temporary file and renamed into place.
Existing files are rejected unless overwrite is true. With durable
enabled, BTPC also requests file and parent-directory synchronization before
returning.
Args:
- path: Payload file or directory to traverse deterministically.
- destination: Torrent file to create atomically.
- options: Creation settings.
Noneuses :class:CreateOptionsdefaults. - overwrite: Replace an existing destination when true.
- durable: Request durable file and directory synchronization.
- progress: Optional callback receiving ``(completed_bytes, total_bytes, completed_pieces)`. Callback exceptions propagate unchanged.
- cancellation: Cooperative cancellation token.
Returns:
- **The same result data returned by :**func:
create_bytes.
Raises:
- PathError: If payload or destination I/O fails, including a disallowed overwrite.
- MetainfoError: If options or payload structure violate protocol rules.
- CancelledError: If
cancellationis requested. - Exception: Any exception raised by
progress.
Examples:
>>> from pathlib import Path
>>> from tempfile import TemporaryDirectory
>>> from btpc import CreateOptions, create
>>> with TemporaryDirectory() as directory:
... root = Path(directory)
... payload = root / "hello.txt"
... destination = root / "hello.torrent"
... _ = payload.write_bytes(b"hello torrent\n")
... result = create(
... payload,
... destination,
... options=CreateOptions(creation_date=0, threads=1),
... )
... assert destination.read_bytes() == result.bytes
create_bytes
create_bytes(path: str | PathLike[str], *, options: CreateOptions | None = None, progress: Callable[[int, int, int], None] | None = None, cancellation: CancellationToken | None = None) -> CreateResult
Create canonical metainfo without writing a torrent file.
Args:
- path: Payload file or directory to traverse deterministically.
- options: Creation settings.
Noneuses :class:CreateOptionsdefaults. - progress: Optional callback receiving ``(completed_bytes, total_bytes, completed_pieces)`. Exceptions raised by the callback propagate to the caller and stop creation.
- cancellation: Cooperative cancellation token checked during traversal and hashing.
Returns:
The immutable result, including generated bytes, applicable info hashes, selected piece length, and phase metrics.
Raises:
- PathError: If the payload cannot be traversed or read.
- MetainfoError: If options or payload structure violate protocol rules.
- CancelledError: If
cancellationis requested. - Exception: Any exception raised by
progress.
Examples:
>>> from pathlib import Path
>>> from tempfile import TemporaryDirectory
>>> from btpc import CreateOptions, create_bytes
>>> with TemporaryDirectory() as directory:
... payload = Path(directory) / "hello.txt"
... _ = payload.write_bytes(b"hello torrent\n")
... result = create_bytes(
... payload,
... options=CreateOptions(creation_date=0, threads=1),
... )
... assert result.file_count == 1