torrent

pydantic model TorrentBase[source]

Show JSON schema
{
   "title": "TorrentBase",
   "type": "object",
   "properties": {
      "announce": {
         "anyOf": [
            {
               "type": "string"
            },
            {
               "type": "null"
            }
         ],
         "default": null,
         "title": "Announce"
      },
      "announce-list": {
         "anyOf": [
            {
               "items": {
                  "items": {
                     "type": "string"
                  },
                  "type": "array"
               },
               "type": "array"
            },
            {
               "type": "null"
            }
         ],
         "default": null,
         "title": "Announce-List"
      },
      "comment": {
         "anyOf": [
            {
               "type": "string"
            },
            {
               "type": "null"
            }
         ],
         "default": null,
         "title": "Comment"
      },
      "created by": {
         "anyOf": [
            {
               "type": "string"
            },
            {
               "type": "null"
            }
         ],
         "default": null,
         "title": "Created By"
      },
      "creation date": {
         "anyOf": [
            {
               "format": "date-time",
               "type": "string"
            },
            {
               "type": "null"
            }
         ],
         "default": null,
         "title": "Creation Date"
      },
      "info": {
         "oneOf": [
            {
               "$ref": "#/$defs/InfoDictV1"
            },
            {
               "$ref": "#/$defs/InfoDictV2"
            },
            {
               "$ref": "#/$defs/InfoDictHybrid"
            }
         ],
         "title": "Info"
      },
      "piece layers": {
         "anyOf": [
            {
               "additionalProperties": {
                  "items": {
                     "format": "binary",
                     "maxLength": 32,
                     "minLength": 32,
                     "type": "string"
                  },
                  "type": "array"
               },
               "propertyNames": {
                  "format": "binary",
                  "maxLength": 32,
                  "minLength": 32
               },
               "type": "object"
            },
            {
               "type": "null"
            }
         ],
         "default": null,
         "title": "Piece Layers"
      },
      "url-list": {
         "anyOf": [
            {
               "items": {
                  "type": "string"
               },
               "type": "array"
            },
            {
               "type": "null"
            }
         ],
         "default": null,
         "description": "List of webseeds",
         "title": "Url-List"
      }
   },
   "$defs": {
      "FileItem": {
         "additionalProperties": true,
         "properties": {
            "length": {
               "minimum": 0,
               "title": "Length",
               "type": "integer"
            },
            "path": {
               "items": {
                  "type": "string"
               },
               "title": "Path",
               "type": "array"
            },
            "attr": {
               "anyOf": [
                  {
                     "format": "binary",
                     "type": "string"
                  },
                  {
                     "type": "null"
                  }
               ],
               "default": null,
               "title": "Attr"
            }
         },
         "required": [
            "length",
            "path"
         ],
         "title": "FileItem",
         "type": "object"
      },
      "FileTreeItem": {
         "properties": {
            "length": {
               "title": "Length",
               "type": "integer"
            },
            "pieces root": {
               "format": "binary",
               "maxLength": 32,
               "minLength": 32,
               "title": "Pieces Root",
               "type": "string"
            }
         },
         "required": [
            "length"
         ],
         "title": "FileTreeItem",
         "type": "object"
      },
      "InfoDictHybrid": {
         "additionalProperties": true,
         "description": "An infodict of a valid v1/v2 hybrid torrent",
         "properties": {
            "name": {
               "title": "Name",
               "type": "string"
            },
            "source": {
               "anyOf": [
                  {
                     "type": "string"
                  },
                  {
                     "type": "null"
                  }
               ],
               "default": null,
               "title": "Source"
            },
            "pieces": {
               "items": {
                  "format": "binary",
                  "maxLength": 20,
                  "minLength": 20,
                  "type": "string"
               },
               "title": "Pieces",
               "type": "array"
            },
            "length": {
               "anyOf": [
                  {
                     "minimum": 0,
                     "type": "integer"
                  },
                  {
                     "type": "null"
                  }
               ],
               "default": null,
               "title": "Length"
            },
            "files": {
               "anyOf": [
                  {
                     "items": {
                        "$ref": "#/$defs/FileItem"
                     },
                     "minItems": 1,
                     "type": "array"
                  },
                  {
                     "type": "null"
                  }
               ],
               "default": null,
               "title": "Files"
            },
            "piece length": {
               "title": "Piece Length",
               "type": "integer"
            },
            "meta version": {
               "default": 2,
               "title": "Meta Version",
               "type": "integer"
            },
            "file tree": {
               "$ref": "#/$defs/_FileTreeType"
            }
         },
         "required": [
            "name",
            "pieces",
            "piece length",
            "file tree"
         ],
         "title": "InfoDictHybrid",
         "type": "object"
      },
      "InfoDictV1": {
         "additionalProperties": true,
         "description": "An infodict from a valid V1 torrent",
         "properties": {
            "name": {
               "title": "Name",
               "type": "string"
            },
            "source": {
               "anyOf": [
                  {
                     "type": "string"
                  },
                  {
                     "type": "null"
                  }
               ],
               "default": null,
               "title": "Source"
            },
            "pieces": {
               "items": {
                  "format": "binary",
                  "maxLength": 20,
                  "minLength": 20,
                  "type": "string"
               },
               "title": "Pieces",
               "type": "array"
            },
            "length": {
               "anyOf": [
                  {
                     "minimum": 0,
                     "type": "integer"
                  },
                  {
                     "type": "null"
                  }
               ],
               "default": null,
               "title": "Length"
            },
            "files": {
               "anyOf": [
                  {
                     "items": {
                        "$ref": "#/$defs/FileItem"
                     },
                     "minItems": 1,
                     "type": "array"
                  },
                  {
                     "type": "null"
                  }
               ],
               "default": null,
               "title": "Files"
            },
            "piece length": {
               "title": "Piece Length",
               "type": "integer"
            }
         },
         "required": [
            "name",
            "pieces",
            "piece length"
         ],
         "title": "InfoDictV1",
         "type": "object"
      },
      "InfoDictV2": {
         "additionalProperties": true,
         "description": "An infodict from a valid V2 torrent",
         "properties": {
            "name": {
               "title": "Name",
               "type": "string"
            },
            "source": {
               "anyOf": [
                  {
                     "type": "string"
                  },
                  {
                     "type": "null"
                  }
               ],
               "default": null,
               "title": "Source"
            },
            "meta version": {
               "default": 2,
               "title": "Meta Version",
               "type": "integer"
            },
            "file tree": {
               "$ref": "#/$defs/_FileTreeType"
            },
            "piece length": {
               "title": "Piece Length",
               "type": "integer"
            }
         },
         "required": [
            "name",
            "file tree",
            "piece length"
         ],
         "title": "InfoDictV2",
         "type": "object"
      },
      "_FileTreeType": {
         "additionalProperties": {
            "anyOf": [
               {
                  "additionalProperties": {
                     "$ref": "#/$defs/FileTreeItem"
                  },
                  "propertyNames": {
                     "const": ""
                  },
                  "type": "object"
               },
               {
                  "$ref": "#/$defs/_FileTreeType"
               }
            ]
         },
         "propertyNames": {
            "format": "binary"
         },
         "type": "object"
      }
   },
   "additionalProperties": true,
   "required": [
      "info"
   ]
}

Config:
  • populate_by_name: bool = True

  • extra: str = allow

  • validate_by_alias: bool = True

  • validate_by_name: bool = True

Fields:
field announce: Annotated[str, PlainSerializer(func=_to_bytes, return_type=PydanticUndefined, when_used=always)] | None = None
field announce_list: list[list[Annotated[str, PlainSerializer(func=_to_bytes, return_type=PydanticUndefined, when_used=always)]]] | None = None (alias 'announce-list')
field comment: Annotated[str, PlainSerializer(func=_to_bytes, return_type=PydanticUndefined, when_used=always)] | None = None
field created_by: Annotated[str, PlainSerializer(func=_to_bytes, return_type=PydanticUndefined, when_used=always)] | None = None (alias 'created by')
field creation_date: Annotated[datetime, BeforeValidator(func=_timestamp_to_datetime, json_schema_input_type=PydanticUndefined), PlainSerializer(func=_datetime_to_timestamp, return_type=PydanticUndefined, when_used=always)] | None = None (alias 'creation date')
field info: Annotated[Annotated[InfoDictV1, Tag(tag=v1)] | Annotated[InfoDictV2, Tag(tag=v2)] | Annotated[InfoDictHybrid, Tag(tag=hybrid)], Discriminator(discriminator=infodict_discriminator, custom_error_type=None, custom_error_message=None, custom_error_context=None)] [Required]
Constraints:
  • discriminator = <function infodict_discriminator at 0x70dff2db5440>

field piece_layers: dict[Annotated[bytes, Len(min_length=32, max_length=32), PlainSerializer(func=_serialize_hash, return_type=PydanticUndefined, when_used=always)], Annotated[list[Annotated[bytes, Len(min_length=32, max_length=32), PlainSerializer(func=_serialize_hash, return_type=PydanticUndefined, when_used=always)]], BeforeValidator(func=_validate_v2_hash, json_schema_input_type=PydanticUndefined), WrapSerializer(func=_serialize_v2_hash, return_type=PydanticUndefined, when_used=always)]] | None = None (alias 'piece layers')
field url_list: Annotated[list[Annotated[str, PlainSerializer(func=_to_bytes, return_type=PydanticUndefined, when_used=always)]], BeforeValidator(func=_to_list, json_schema_input_type=PydanticUndefined), WrapSerializer(func=_from_list, return_type=PydanticUndefined, when_used=always)] | None = None (alias 'url-list')

List of webseeds

classmethod from_decoded(decoded: dict[str | bytes, Any], context: dict | None = None, **data: Any) Self[source]

Create from bdecoded dict

classmethod read(path: Path | str, context: dict | None = None) Self[source]
classmethod read_stream(stream: BinaryIO, context: dict | None = None) Self[source]
model_dump_torrent(mode: Literal['str', 'binary'] = 'str', **kwargs: Any) dict[source]

Dump the model into a dictionary that can be bencoded into a torrent

Parameters:
  • mode ("str", "binary") – str returns as a ‘python’ version of the torrent, with string keys and serializers applied. binary roundtrips to and from bencoding.

  • kwargs – forwarded to pydantic.BaseModel.model_dump()

model_post_init(context: Any, /) None

This function is meant to behave like a BaseModel method to initialise private attributes.

It takes context as an argument since that’s what pydantic-core passes when calling it.

Parameters:
  • self – The BaseModel instance.

  • context – The context.

pprint(verbose: int = 0) None[source]

Pretty print the torrent.

See pprint()

property files: list[GenericFileItem]

Common access to file information from both v1 and v2 torrents

property flat_files: dict[str, FileTreeItem] | None

A flattened version of the v2 file tree

property flat_trackers: list[list[str]]
property n_files: int

Total number of files described by the torrent, excluding padfiles

property torrent_version: TorrentVersion
property total_size: int

Total size of the torrent, excluding padfiles, in bytes

property v1_infohash: str | None

hex-encoded SHA1 of the infodict

property v2_infohash: str | None

hex-encoded SHA256 of the infodict

property webseeds: list[str] | None

alias to url_list

pydantic model Torrent[source]

A valid torrent file, including hashes.

Show JSON schema
{
   "title": "Torrent",
   "description": "A valid torrent file, including hashes.",
   "type": "object",
   "properties": {
      "announce": {
         "anyOf": [
            {
               "type": "string"
            },
            {
               "type": "null"
            }
         ],
         "default": null,
         "title": "Announce"
      },
      "announce-list": {
         "anyOf": [
            {
               "items": {
                  "items": {
                     "type": "string"
                  },
                  "type": "array"
               },
               "type": "array"
            },
            {
               "type": "null"
            }
         ],
         "default": null,
         "title": "Announce-List"
      },
      "comment": {
         "anyOf": [
            {
               "type": "string"
            },
            {
               "type": "null"
            }
         ],
         "default": null,
         "title": "Comment"
      },
      "created by": {
         "anyOf": [
            {
               "type": "string"
            },
            {
               "type": "null"
            }
         ],
         "default": null,
         "title": "Created By"
      },
      "creation date": {
         "anyOf": [
            {
               "format": "date-time",
               "type": "string"
            },
            {
               "type": "null"
            }
         ],
         "default": null,
         "title": "Creation Date"
      },
      "info": {
         "oneOf": [
            {
               "$ref": "#/$defs/InfoDictV1"
            },
            {
               "$ref": "#/$defs/InfoDictV2"
            },
            {
               "$ref": "#/$defs/InfoDictHybrid"
            }
         ],
         "title": "Info"
      },
      "piece layers": {
         "anyOf": [
            {
               "additionalProperties": {
                  "items": {
                     "format": "binary",
                     "maxLength": 32,
                     "minLength": 32,
                     "type": "string"
                  },
                  "type": "array"
               },
               "propertyNames": {
                  "format": "binary",
                  "maxLength": 32,
                  "minLength": 32
               },
               "type": "object"
            },
            {
               "type": "null"
            }
         ],
         "default": null,
         "title": "Piece Layers"
      },
      "url-list": {
         "anyOf": [
            {
               "items": {
                  "type": "string"
               },
               "type": "array"
            },
            {
               "type": "null"
            }
         ],
         "default": null,
         "description": "List of webseeds",
         "title": "Url-List"
      }
   },
   "$defs": {
      "FileItem": {
         "additionalProperties": true,
         "properties": {
            "length": {
               "minimum": 0,
               "title": "Length",
               "type": "integer"
            },
            "path": {
               "items": {
                  "type": "string"
               },
               "title": "Path",
               "type": "array"
            },
            "attr": {
               "anyOf": [
                  {
                     "format": "binary",
                     "type": "string"
                  },
                  {
                     "type": "null"
                  }
               ],
               "default": null,
               "title": "Attr"
            }
         },
         "required": [
            "length",
            "path"
         ],
         "title": "FileItem",
         "type": "object"
      },
      "FileTreeItem": {
         "properties": {
            "length": {
               "title": "Length",
               "type": "integer"
            },
            "pieces root": {
               "format": "binary",
               "maxLength": 32,
               "minLength": 32,
               "title": "Pieces Root",
               "type": "string"
            }
         },
         "required": [
            "length"
         ],
         "title": "FileTreeItem",
         "type": "object"
      },
      "InfoDictHybrid": {
         "additionalProperties": true,
         "description": "An infodict of a valid v1/v2 hybrid torrent",
         "properties": {
            "name": {
               "title": "Name",
               "type": "string"
            },
            "source": {
               "anyOf": [
                  {
                     "type": "string"
                  },
                  {
                     "type": "null"
                  }
               ],
               "default": null,
               "title": "Source"
            },
            "pieces": {
               "items": {
                  "format": "binary",
                  "maxLength": 20,
                  "minLength": 20,
                  "type": "string"
               },
               "title": "Pieces",
               "type": "array"
            },
            "length": {
               "anyOf": [
                  {
                     "minimum": 0,
                     "type": "integer"
                  },
                  {
                     "type": "null"
                  }
               ],
               "default": null,
               "title": "Length"
            },
            "files": {
               "anyOf": [
                  {
                     "items": {
                        "$ref": "#/$defs/FileItem"
                     },
                     "minItems": 1,
                     "type": "array"
                  },
                  {
                     "type": "null"
                  }
               ],
               "default": null,
               "title": "Files"
            },
            "piece length": {
               "title": "Piece Length",
               "type": "integer"
            },
            "meta version": {
               "default": 2,
               "title": "Meta Version",
               "type": "integer"
            },
            "file tree": {
               "$ref": "#/$defs/_FileTreeType"
            }
         },
         "required": [
            "name",
            "pieces",
            "piece length",
            "file tree"
         ],
         "title": "InfoDictHybrid",
         "type": "object"
      },
      "InfoDictV1": {
         "additionalProperties": true,
         "description": "An infodict from a valid V1 torrent",
         "properties": {
            "name": {
               "title": "Name",
               "type": "string"
            },
            "source": {
               "anyOf": [
                  {
                     "type": "string"
                  },
                  {
                     "type": "null"
                  }
               ],
               "default": null,
               "title": "Source"
            },
            "pieces": {
               "items": {
                  "format": "binary",
                  "maxLength": 20,
                  "minLength": 20,
                  "type": "string"
               },
               "title": "Pieces",
               "type": "array"
            },
            "length": {
               "anyOf": [
                  {
                     "minimum": 0,
                     "type": "integer"
                  },
                  {
                     "type": "null"
                  }
               ],
               "default": null,
               "title": "Length"
            },
            "files": {
               "anyOf": [
                  {
                     "items": {
                        "$ref": "#/$defs/FileItem"
                     },
                     "minItems": 1,
                     "type": "array"
                  },
                  {
                     "type": "null"
                  }
               ],
               "default": null,
               "title": "Files"
            },
            "piece length": {
               "title": "Piece Length",
               "type": "integer"
            }
         },
         "required": [
            "name",
            "pieces",
            "piece length"
         ],
         "title": "InfoDictV1",
         "type": "object"
      },
      "InfoDictV2": {
         "additionalProperties": true,
         "description": "An infodict from a valid V2 torrent",
         "properties": {
            "name": {
               "title": "Name",
               "type": "string"
            },
            "source": {
               "anyOf": [
                  {
                     "type": "string"
                  },
                  {
                     "type": "null"
                  }
               ],
               "default": null,
               "title": "Source"
            },
            "meta version": {
               "default": 2,
               "title": "Meta Version",
               "type": "integer"
            },
            "file tree": {
               "$ref": "#/$defs/_FileTreeType"
            },
            "piece length": {
               "title": "Piece Length",
               "type": "integer"
            }
         },
         "required": [
            "name",
            "file tree",
            "piece length"
         ],
         "title": "InfoDictV2",
         "type": "object"
      },
      "_FileTreeType": {
         "additionalProperties": {
            "anyOf": [
               {
                  "additionalProperties": {
                     "$ref": "#/$defs/FileTreeItem"
                  },
                  "propertyNames": {
                     "const": ""
                  },
                  "type": "object"
               },
               {
                  "$ref": "#/$defs/_FileTreeType"
               }
            ]
         },
         "propertyNames": {
            "format": "binary"
         },
         "type": "object"
      }
   },
   "additionalProperties": true,
   "required": [
      "info"
   ]
}

Config:
  • populate_by_name: bool = True

  • extra: str = allow

  • validate_by_alias: bool = True

  • validate_by_name: bool = True

Fields:

Validators:
bencode() bytes[source]
model_post_init(context: Any, /) None

This function is meant to behave like a BaseModel method to initialise private attributes.

It takes context as an argument since that’s what pydantic-core passes when calling it.

Parameters:
  • self – The BaseModel instance.

  • context – The context.

validator piece_layers_if_v2  »  all fields[source]

If we are a v2 or hybrid torrent, we should have piece layers

validator pieces_layers_correct  »  all fields[source]

All files with a length longer than the piece length should be in piece layers, Piece layers should have the correct number of hashes

v1_piece_range(piece_idx: int) V1PieceRange[source]

Get a v1 piece range from the piece index

v2_piece_range(file: str, piece_idx: int = 0) V2PieceRange[source]

Get a v2 piece range from a file path and optional piece index.

If piece_idx is not provided (default to 0)…

  • If the file is larger than the piece length, gets the 0th piece.

  • If the file is smaller than the piece length, the range corresponds to the whole file, the hash is the root hash, and piece_idx is ignored.

write(path: Path) None[source]

Write the torrent to disk

property file_size: int

Size of the generated torrent file, in bytes

pprint(t: TorrentBase, verbose: int = 0) None[source]

Print the contents of a torrent file.

By default, prints only the top-level metadata in a way that should always be smaller than one screen.

Increase verbosity to show more of the torrent.

Hashes are printed as hexadecimal numbers and split into individual pieces, but they are properly encoded in the torrent.

Parameters:
  • t (Torrent) – The torrent to print.

  • verbose (int) –

    Level of detail to print.

    • 1 show files in separate table

    • 2 show truncated v1 piece hashes

    • 3 show everything as-is