Skip to content

API Reference

PyBen is a library for decoding/encoding data, with the bencode specification.

Bencode is commonly used for encoding Bittorrent Protocol Metafiles (.torrent).

Modules

  • api
  • classes
  • bencode

Classes

  • Bendecoder
  • Benencoder

Functions

  • bendecode
  • benencode
  • dump
  • dumps
  • load
  • loads

api

Bencode utility library.

Features simple API inspired by json and pickle modules in stdlib.

Functions

  • dump
  • dumps
  • load
  • loads
  • tojson

Usage Examples

Encode inline code:
>>> import os
>>> import pyben
>>> data = {"item1": ["item2", 3, [4], {5: "item6"}]}
>>> encoded = pyben.dumps(data)
>>> encoded
... b'd5:item1l5:item2i3eli4eedi5e5:item6eee'
Encode to file:
>>> fd = "path/to/file"
>>> pyben.dump(data, fd)
>>> os.path.exists(fd)
... True
>>> encoded_file = open(fd, "rb").read()
>>> encoded_file == encoded
... True
Decode inline code:
>>> decoded = pybem.loads(encoded)
>>> decoded
... {'item1': ['item2', 3, [4], {5: 'item6'}]}
>>> decoded == data
... True
Decode from file:
>>> decoded_file = pyben.load(fd)
>>> decoded_file
... {'item1': ['item2', 3, [4], {5: 'item6'}]}
>>> decoded_file == data
... True

dump(obj, buffer)

Shortcut function for bencode encode data and write to file.

Works effectively the same as it's json equivelant except also accepts a path as well as an open fileIO.


obj : any Data to be encoded. buffer : str or BytesIO File of path-like to write the data to.

Source code in pyben\api.py
def dump(obj, buffer):
    """
    Shortcut function for bencode encode data and write to file.

    Works effectively the same as it's json equivelant except also
    accepts a path as well as an open fileIO.

    Args:
    ----
    obj : any
        Data to be encoded.
    buffer : `str` or `BytesIO`
        File of path-like to write the data to.

    """
    encoded = benencode(obj)

    if not hasattr(buffer, "write"):
        with open(buffer, "wb") as _fd:
            _fd.write(encoded)
    else:
        buffer.write(encoded)

dumps(obj)

Shortuct function to encoding given obj to bencode encoding.

Args

obj : any Object to be encoded.py.

Returns

bytes : Encoded data.

Source code in pyben\api.py
def dumps(obj):
    """
    Shortuct function to encoding given obj to bencode encoding.

    Args
    ----
    obj : `any`
        Object to be encoded.py.

    Returns
    -------
    `bytes` :
        Encoded data.

    """
    return benencode(obj)

load(buffer)

Load bencoded data from a file of path object and decodes it.

Args

buffer : str or BytesIO Open and/or read data from file to be decoded.

Returns

any : (commonly dict), Decoded contents of file.

Source code in pyben\api.py
def load(buffer):
    """
    Load bencoded data from a file of path object and decodes it.

    Args
    ----
    buffer : `str` or `BytesIO`
        Open and/or read data from file to be decoded.

    Returns
    -------
    `any` :
        (commonly `dict`), Decoded contents of file.

    """
    if buffer in [None, ""]:
        raise FilePathError(buffer)

    if hasattr(buffer, "read"):
        decoded, _ = bendecode(buffer.read())
    else:
        try:
            with open(buffer, "rb") as _fd:
                decoded, _ = bendecode(_fd.read())
        except FileNotFoundError as excp:
            raise FilePathError(buffer) from excp

    return decoded

loads(encoded)

Shortcut function for decoding encoded data.

Args

encoded : bytes Bencoded data.

Returns

any : (commonly dict), Decoded data.

Source code in pyben\api.py
def loads(encoded):
    """
    Shortcut function for decoding encoded data.

    Args
    ----
    encoded : `bytes`
        Bencoded data.

    Returns
    -------
    `any` :
        (commonly `dict`), Decoded data.

    """
    decoded, _ = bendecode(encoded)
    return decoded

tojson(meta)

Create json searializable data from bencode.

Parameters

meta : bytes or dict encoded or decoded bencode data.

Returns

json : dict bencode data as json serializable object dictionary.

Source code in pyben\api.py
def tojson(meta):
    """Create json searializable data from bencode.

    Parameters
    ----------
    meta : `bytes` or `dict`
        encoded or decoded bencode data.

    Returns
    -------
    json : `dict`
        bencode data as json serializable object dictionary.
    """
    if isinstance(meta, (bytes, bytearray)):
        meta = loads(meta)

    def check_instance(item):
        """Check and format item according to it's type.

        Parameters
        ----------
        item : `any`
            data that needs to be checked.

        Returns
        -------
        item : `any`
            formatted data cast to type.
        """
        if isinstance(item, (str, bytes, int, float)):
            if isinstance(item, bytes):
                try:
                    return item.decode()
                except UnicodeDecodeError:
                    return item.hex()
            else:
                return item
        elif isinstance(item, Mapping):
            return tojson(item)
        return [isinstance(val) for val in item]

    json = {}
    for k, v in meta.items():
        if isinstance(k, (bytes, bytearray)):
            try:
                key = k.decode()
            except UnicodeDecodeError:
                key = k.hex()
            json[key] = check_instance(v)
        else:
            json[k] = check_instance(v)
    return json

bencode

API helper functions for decoding and encoding data with bencode format.

Functions

  • bendecode
  • bendecode_dict
  • bendecode_int
  • bendecode_list
  • bendecode_str

  • benencode

  • bencode_bytes
  • bencode_dict
  • bencode_int
  • bencode_list
  • bencode_str

bencode_bytes(bits)

Encode bytes.

Args

bits : bytes Bytes treated as a byte-string literal.

Returns

bytes: Bencode encoded byte string literal.

Source code in pyben\bencode.py
def bencode_bytes(bits):
    """
    Encode bytes.

    Args
    ----
    bits : `bytes`
        Bytes treated as a byte-string literal.

    Returns
    -------
    `bytes`:
        Bencode encoded byte string literal.

    """
    size = str(len(bits)) + ":"
    return size.encode("utf-8") + bits

bencode_dict(dic)

Encode dictionary and contents.

Args

dic : dict Any dictionary containing items that can be bencoded.

Returns

bytes : Bencoded key, value pairs of data.

Source code in pyben\bencode.py
def bencode_dict(dic):
    """
    Encode dictionary and contents.

    Args
    ----
    dic : `dict`
        Any dictionary containing items that can be bencoded.

    Returns
    -------
    `bytes` :
        Bencoded key, value pairs of data.
    """
    result = b"d"

    for key, val in dic.items():
        result += b"".join([benencode(key), benencode(val)])

    return result + b"e"

bencode_int(i)

Encode integer type.

Args

i : int Number that needs encoding.

Returns

bytes : Bencoded Integer.

Source code in pyben\bencode.py
def bencode_int(i):
    """
    Encode integer type.

    Args
    ----
    i : `int`
        Number that needs encoding.

    Returns
    -------
    `bytes` :
        Bencoded Integer.

    """
    return ("i" + str(i) + "e").encode("utf-8")

bencode_list(elems)

Encode list and contents.

Args

elems : list List of items for bencoding.

Returns

bytes : Bencoded list and contents.

Source code in pyben\bencode.py
def bencode_list(elems):
    """
    Encode list and contents.

    Args
    ----
    elems : `list`
        List of items for bencoding.

    Returns
    -------
    `bytes` :
        Bencoded list and contents.

    """
    arr = bytearray("l", encoding="utf-8")

    for elem in elems:
        encoded = benencode(elem)
        arr.extend(encoded)

    arr.extend(b"e")
    return arr

bencode_str(txt)

Encode string literals.

Args

txt : str Any text string.

Returns

bytes : Bencoded string literal.

Source code in pyben\bencode.py
def bencode_str(txt):
    """
    Encode string literals.

    Args
    ----
    txt : `str`
        Any text string.

    Returns
    -------
    `bytes` :
        Bencoded string literal.

    """
    size = str(len(txt)) + ":"
    return size.encode("utf-8") + txt.encode("utf-8")

bendecode(bits)

Decode bencoded data.

Args

bits : bytes Bencode encoded data.

Raises

DecodeError : Malformed data.

Returns

any : Bencode decoded data.

Source code in pyben\bencode.py
def bendecode(bits):
    """
    Decode bencoded data.

    Args
    ----
    bits : `bytes`
        Bencode encoded data.

    Raises
    ------
    `DecodeError` :
        Malformed data.

    Returns
    -------
    any :
        Bencode decoded data.

    """
    if bits.startswith(b"i"):
        match, feed = bendecode_int(bits)
        return match, feed

    if chr(bits[0]).isdigit():
        match, feed = bendecode_str(bits)
        return match, feed

    if bits.startswith(b"l"):
        lst, feed = bendecode_list(bits)
        return lst, feed

    if bits.startswith(b"d"):
        dic, feed = bendecode_dict(bits)
        return dic, feed

    raise DecodeError(bits)

bendecode_dict(bits)

Decode dictionary and it's contents.

Args

bits : bytes Bencoded dictionary.

Returns

dict Decoded dictionary and contents

Source code in pyben\bencode.py
def bendecode_dict(bits):
    """
    Decode dictionary and it's contents.

    Args
    ----
    bits : `bytes`
        Bencoded dictionary.

    Returns
    -------
    `dict`
        Decoded dictionary and contents

    """
    dic, feed = {}, 1

    while not bits[feed:].startswith(b"e"):
        match1, rest = bendecode(bits[feed:])
        feed += rest
        match2, rest = bendecode(bits[feed:])
        feed += rest
        dic[match1] = match2

    feed += 1
    return dic, feed

bendecode_int(bits)

Decode digits.

Args

bits : bytes Bencoded intiger bytes

Returns

int : Decoded int value.

Source code in pyben\bencode.py
def bendecode_int(bits):
    """
    Decode digits.

    Args
    ----
    bits : `bytes`
        Bencoded intiger bytes

    Returns
    -------
    `int` :
        Decoded int value.

    """
    obj = re.match(br"i(-?\d+)e", bits)
    return int(obj.group(1)), obj.end()

bendecode_list(bits)

Decode list and list contents.

Args

bits : bytes Bencoded list.

Returns

list : Bencode decoded list and contents.

Source code in pyben\bencode.py
def bendecode_list(bits):
    """
    Decode list and list contents.

    Args
    ----
    bits : `bytes`
        Bencoded list.

    Returns
    -------
    `list` :
        Bencode decoded list and contents.

    """
    lst, feed = [], 1

    while not bits[feed:].startswith(b"e"):
        match, rest = bendecode(bits[feed:])
        lst.append(match)
        feed += rest

    feed += 1
    return lst, feed

bendecode_str(units)

Bendecode string types.

Args

bits : bytes Bencoded string.

Returns

str : Decoded data string.

Source code in pyben\bencode.py
def bendecode_str(units):
    """
    Bendecode string types.

    Args
    ----
    bits : `bytes`
        Bencoded string.

    Returns
    -------
    `str` :
        Decoded data string.

    """
    match = re.match(br"(\d+):", units)
    word_len, start = int(match.groups()[0]), match.span()[1]
    end = start + word_len
    text = units[start:end]

    try:
        text = text.decode("utf-8")

    except UnicodeDecodeError:
        pass

    return text, end

benencode(val)

Encode data with bencoding.

Args

val : any Data for encoding.

Raises

EncodeError : Cannot interpret data.

Returns

bytes : Bencoded data.

Source code in pyben\bencode.py
def benencode(val):
    """
    Encode data with bencoding.

    Args
    ----
    val : any
        Data for encoding.

    Raises
    ------
    `EncodeError` :
        Cannot interpret data.

    Returns
    -------
    `bytes` :
        Bencoded data.

    """
    if isinstance(val, str):
        return bencode_str(val)

    if isinstance(val, int):
        return bencode_int(val)

    if isinstance(val, list):
        return bencode_list(val)

    if isinstance(val, dict):
        return bencode_dict(val)

    if hasattr(val, "hex"):
        return bencode_bytes(val)

    if isinstance(val, tuple):
        return bencode_list(list(val))

    raise EncodeError(val)

classes

OOP implementation of bencode decoders and encoders.

This style is not recommended as it can get bulky. The json-like api from the bencode.py module is much easier to use.

Classes

  • Bendecoder
  • Benencoder

Bendecoder

Decode class contains all decode methods.

__init__(self, data=None) special

Initialize instance with optional pre compiled data.


data : bytes or bytearray (Optional) (default=None) Target data for decoding.

Source code in pyben\classes.py
def __init__(self, data=None):
    """
    Initialize instance with optional pre compiled data.

    Args:
    ----
    data : `bytes` or `bytearray`
        (Optional) (default=None) Target data for decoding.

    """
    self.data = data
    self.decoded = None

decode(self, data=None)

Decode bencoded data.

Args

bits : bytes bencoded data for decoding.

Returns

any : the decoded data.

Source code in pyben\classes.py
def decode(self, data=None):
    """
    Decode bencoded data.

    Args
    ----
    bits : ``bytes``
        bencoded data for decoding.

    Returns
    -------
    any :
        the decoded data.

    """
    data = self.data if not data else data
    self.decoded, _ = self._decode(bits=data)
    return self.decoded

load(item) classmethod

Extract contents from path/path-like and return Decoded data.

Args

path : str or path-like Path containing bencoded data.

Raises

FilePathError: Incorrect path or IOBuffer doesnt exist.

Returns

any Decoded contents of file, Usually a dictionary.

Source code in pyben\classes.py
@classmethod
def load(cls, item):
    """
    Extract contents from path/path-like and return Decoded data.

    Args
    ----
    path : `str` or `path-like`
        Path containing bencoded data.

    Raises
    ------
    `FilePathError`:
        Incorrect path or IOBuffer doesnt exist.

    Returns
    -------
    any
        Decoded contents of file, Usually a dictionary.

    """
    decoder = cls()
    if hasattr(item, "read"):
        data = item.read()

    elif os.path.exists(item) and os.path.isfile(item):
        with open(item, "rb") as _fd:
            data = _fd.read()
    return decoder.decode(data)

loads(data) classmethod

Shortcut to Decode raw bencoded data.

Args

data : bytes or bytearray Bendencoded bytes.

Returns

any Decoded data usually a dictionary.

Source code in pyben\classes.py
@classmethod
def loads(cls, data):
    """
    Shortcut to Decode raw bencoded data.

    Args
    ----
    data : ``bytes`` or `bytearray`
        Bendencoded `bytes`.

    Returns
    -------
    any
        Decoded data usually a dictionary.

    """
    decoder = cls()
    return decoder.decode(data)

Benencoder

Encoder for bencode encoding used for Bittorrent meta-files.

__init__(self, data=None) special

Initialize Benencoder insance with optional pre compiled data.


data : any (Optional) Target data for encoding. Defaults to None.

Source code in pyben\classes.py
def __init__(self, data=None):
    """
    Initialize Benencoder insance with optional pre compiled data.

    Args:
    ----
    data : any
        (Optional) Target data for encoding. Defaults to None.

    """
    self.data = data
    self.encoded = None

dump(data, path) classmethod

Shortcut Classmethod for encoding data and writing to file.

Args

data : any Raw data to be encoded, usually dict.txt path : path-like or BytesIO Where encoded data should be written to.py

Returns

bool : Return True if success.txt

Source code in pyben\classes.py
@classmethod
def dump(cls, data, path):
    """
    Shortcut Classmethod for encoding data and writing to file.

    Args
    ----
    data : any
        Raw data to be encoded, usually dict.txt
    path : path-like or `BytesIO`
        Where encoded data should be written to.py

    Returns
    -------
    `bool` : Return True if success.txt

    """
    encoded = cls(data).encode()
    if hasattr(path, "write"):
        path.write(encoded)
    else:
        with open(path, "wb") as _fd:
            _fd.write(encoded)
    return True

dumps(data) classmethod

Shortcut method for encoding data and immediately returning it.

Args

data : any Raw data to be encoded usually a dictionary.

Returns

bytes: Encoded data.

Source code in pyben\classes.py
@classmethod
def dumps(cls, data):
    """
    Shortcut method for encoding data and immediately returning it.

    Args
    ----
    data : any
        Raw data to be encoded usually a dictionary.

    Returns
    -------
    `bytes`: Encoded data.

    """
    return cls(data).encode()

encode(self, val=None)

Encode data provided as an arguement or provided at initialization.

Args

val : any, optional Data for encoding. Defaults to None.

Returns

bytes : encoded data

Source code in pyben\classes.py
def encode(self, val=None):
    """
    Encode data provided as an arguement or provided at initialization.

    Args
    ----
    val : any, optional
        Data for encoding. Defaults to None.

    Returns
    -------
    `bytes` : encoded data

    """
    if val is None:
        val = self.data
    self.encoded = self._encode(val)
    return self.encoded

exceptions

Exceptions used throughout the PyBen Package/Library.

DecodeError (Exception)

Error occured during decode process.

Raised when attempting to decode an incompatible bytearray. Mostly it indicates the object is a hash digest and should remian as a bytes object.


val : any Value that cause the exception

__init__(self, val=None) special

Construct Exception DecodeError.

Source code in pyben\exceptions.py
def __init__(self, val=None):
    """Construct Exception DecodeError."""
    msg = f"Decoder is unable to interpret {type(val)} type = {str(val)}"
    super().__init__(msg)

EncodeError (Exception)

Error occured during encoding process.

Raised when attempting to bencode encode an incompatible data type into bencode format. Bencode accepts lists, dicts, strings, integers, and bytes.


val : any Value that cause the exception

__init__(self, val=None) special

Construct Exception EncodeError.

Source code in pyben\exceptions.py
def __init__(self, val=None):
    """Construct Exception EncodeError."""
    msg = f"Encoder is unable to interpret {type(val)} type = {str(val)}"
    super().__init__(msg)

FilePathError (Exception)

Bad path error.

Generally raised when the file at the path specified does not exist.


val : any Value that cause the exception

__init__(self, obj=None) special

Construct Exception Subclass FilePathError.

Source code in pyben\exceptions.py
def __init__(self, obj=None):
    """Construct Exception Subclass FilePathError."""
    msg = f"{str(obj)} doesn't exist or is unavailable."
    super().__init__(msg)

Bencode utility library.

Features simple API inspired by json and pickle modules in stdlib.

Functions

  • dump
  • dumps
  • load
  • loads
  • tojson

Usage Examples

Encode inline code:

>>> import os
>>> import pyben
>>> data = {"item1": ["item2", 3, [4], {5: "item6"}]}
>>> encoded = pyben.dumps(data)
>>> encoded
... b'd5:item1l5:item2i3eli4eedi5e5:item6eee'

Encode to file:

>>> fd = "path/to/file"
>>> pyben.dump(data, fd)
>>> os.path.exists(fd)
... True
>>> encoded_file = open(fd, "rb").read()
>>> encoded_file == encoded
... True

Decode inline code:

>>> decoded = pybem.loads(encoded)
>>> decoded
... {'item1': ['item2', 3, [4], {5: 'item6'}]}
>>> decoded == data
... True

Decode from file:

>>> decoded_file = pyben.load(fd)
>>> decoded_file
... {'item1': ['item2', 3, [4], {5: 'item6'}]}
>>> decoded_file == data
... True

dump(obj, buffer)

Shortcut function for bencode encode data and write to file.

Works effectively the same as it's json equivelant except also accepts a path as well as an open fileIO.


obj : any Data to be encoded. buffer : str or BytesIO File of path-like to write the data to.

Source code in pyben\api.py
def dump(obj, buffer):
    """
    Shortcut function for bencode encode data and write to file.

    Works effectively the same as it's json equivelant except also
    accepts a path as well as an open fileIO.

    Args:
    ----
    obj : any
        Data to be encoded.
    buffer : `str` or `BytesIO`
        File of path-like to write the data to.

    """
    encoded = benencode(obj)

    if not hasattr(buffer, "write"):
        with open(buffer, "wb") as _fd:
            _fd.write(encoded)
    else:
        buffer.write(encoded)

dumps(obj)

Shortuct function to encoding given obj to bencode encoding.

Args

obj : any Object to be encoded.py.

Returns

bytes : Encoded data.

Source code in pyben\api.py
def dumps(obj):
    """
    Shortuct function to encoding given obj to bencode encoding.

    Args
    ----
    obj : `any`
        Object to be encoded.py.

    Returns
    -------
    `bytes` :
        Encoded data.

    """
    return benencode(obj)

load(buffer)

Load bencoded data from a file of path object and decodes it.

Args

buffer : str or BytesIO Open and/or read data from file to be decoded.

Returns

any : (commonly dict), Decoded contents of file.

Source code in pyben\api.py
def load(buffer):
    """
    Load bencoded data from a file of path object and decodes it.

    Args
    ----
    buffer : `str` or `BytesIO`
        Open and/or read data from file to be decoded.

    Returns
    -------
    `any` :
        (commonly `dict`), Decoded contents of file.

    """
    if buffer in [None, ""]:
        raise FilePathError(buffer)

    if hasattr(buffer, "read"):
        decoded, _ = bendecode(buffer.read())
    else:
        try:
            with open(buffer, "rb") as _fd:
                decoded, _ = bendecode(_fd.read())
        except FileNotFoundError as excp:
            raise FilePathError(buffer) from excp

    return decoded

loads(encoded)

Shortcut function for decoding encoded data.

Args

encoded : bytes Bencoded data.

Returns

any : (commonly dict), Decoded data.

Source code in pyben\api.py
def loads(encoded):
    """
    Shortcut function for decoding encoded data.

    Args
    ----
    encoded : `bytes`
        Bencoded data.

    Returns
    -------
    `any` :
        (commonly `dict`), Decoded data.

    """
    decoded, _ = bendecode(encoded)
    return decoded

tojson(meta)

Create json searializable data from bencode.

Parameters

meta : bytes or dict encoded or decoded bencode data.

Returns

json : dict bencode data as json serializable object dictionary.

Source code in pyben\api.py
def tojson(meta):
    """Create json searializable data from bencode.

    Parameters
    ----------
    meta : `bytes` or `dict`
        encoded or decoded bencode data.

    Returns
    -------
    json : `dict`
        bencode data as json serializable object dictionary.
    """
    if isinstance(meta, (bytes, bytearray)):
        meta = loads(meta)

    def check_instance(item):
        """Check and format item according to it's type.

        Parameters
        ----------
        item : `any`
            data that needs to be checked.

        Returns
        -------
        item : `any`
            formatted data cast to type.
        """
        if isinstance(item, (str, bytes, int, float)):
            if isinstance(item, bytes):
                try:
                    return item.decode()
                except UnicodeDecodeError:
                    return item.hex()
            else:
                return item
        elif isinstance(item, Mapping):
            return tojson(item)
        return [isinstance(val) for val in item]

    json = {}
    for k, v in meta.items():
        if isinstance(k, (bytes, bytearray)):
            try:
                key = k.decode()
            except UnicodeDecodeError:
                key = k.hex()
            json[key] = check_instance(v)
        else:
            json[k] = check_instance(v)
    return json

OOP implementation of bencode decoders and encoders.

This style is not recommended as it can get bulky. The json-like api from the bencode.py module is much easier to use.

Classes

  • Bendecoder
  • Benencoder

Bendecoder

Decode class contains all decode methods.

__init__(self, data=None) special

Initialize instance with optional pre compiled data.


data : bytes or bytearray (Optional) (default=None) Target data for decoding.

Source code in pyben\classes.py
def __init__(self, data=None):
    """
    Initialize instance with optional pre compiled data.

    Args:
    ----
    data : `bytes` or `bytearray`
        (Optional) (default=None) Target data for decoding.

    """
    self.data = data
    self.decoded = None

decode(self, data=None)

Decode bencoded data.

Args

bits : bytes bencoded data for decoding.

Returns

any : the decoded data.

Source code in pyben\classes.py
def decode(self, data=None):
    """
    Decode bencoded data.

    Args
    ----
    bits : ``bytes``
        bencoded data for decoding.

    Returns
    -------
    any :
        the decoded data.

    """
    data = self.data if not data else data
    self.decoded, _ = self._decode(bits=data)
    return self.decoded

load(item) classmethod

Extract contents from path/path-like and return Decoded data.

Args

path : str or path-like Path containing bencoded data.

Raises

FilePathError: Incorrect path or IOBuffer doesnt exist.

Returns

any Decoded contents of file, Usually a dictionary.

Source code in pyben\classes.py
@classmethod
def load(cls, item):
    """
    Extract contents from path/path-like and return Decoded data.

    Args
    ----
    path : `str` or `path-like`
        Path containing bencoded data.

    Raises
    ------
    `FilePathError`:
        Incorrect path or IOBuffer doesnt exist.

    Returns
    -------
    any
        Decoded contents of file, Usually a dictionary.

    """
    decoder = cls()
    if hasattr(item, "read"):
        data = item.read()

    elif os.path.exists(item) and os.path.isfile(item):
        with open(item, "rb") as _fd:
            data = _fd.read()
    return decoder.decode(data)

loads(data) classmethod

Shortcut to Decode raw bencoded data.

Args

data : bytes or bytearray Bendencoded bytes.

Returns

any Decoded data usually a dictionary.

Source code in pyben\classes.py
@classmethod
def loads(cls, data):
    """
    Shortcut to Decode raw bencoded data.

    Args
    ----
    data : ``bytes`` or `bytearray`
        Bendencoded `bytes`.

    Returns
    -------
    any
        Decoded data usually a dictionary.

    """
    decoder = cls()
    return decoder.decode(data)

Benencoder

Encoder for bencode encoding used for Bittorrent meta-files.

__init__(self, data=None) special

Initialize Benencoder insance with optional pre compiled data.


data : any (Optional) Target data for encoding. Defaults to None.

Source code in pyben\classes.py
def __init__(self, data=None):
    """
    Initialize Benencoder insance with optional pre compiled data.

    Args:
    ----
    data : any
        (Optional) Target data for encoding. Defaults to None.

    """
    self.data = data
    self.encoded = None

dump(data, path) classmethod

Shortcut Classmethod for encoding data and writing to file.

Args

data : any Raw data to be encoded, usually dict.txt path : path-like or BytesIO Where encoded data should be written to.py

Returns

bool : Return True if success.txt

Source code in pyben\classes.py
@classmethod
def dump(cls, data, path):
    """
    Shortcut Classmethod for encoding data and writing to file.

    Args
    ----
    data : any
        Raw data to be encoded, usually dict.txt
    path : path-like or `BytesIO`
        Where encoded data should be written to.py

    Returns
    -------
    `bool` : Return True if success.txt

    """
    encoded = cls(data).encode()
    if hasattr(path, "write"):
        path.write(encoded)
    else:
        with open(path, "wb") as _fd:
            _fd.write(encoded)
    return True

dumps(data) classmethod

Shortcut method for encoding data and immediately returning it.

Args

data : any Raw data to be encoded usually a dictionary.

Returns

bytes: Encoded data.

Source code in pyben\classes.py
@classmethod
def dumps(cls, data):
    """
    Shortcut method for encoding data and immediately returning it.

    Args
    ----
    data : any
        Raw data to be encoded usually a dictionary.

    Returns
    -------
    `bytes`: Encoded data.

    """
    return cls(data).encode()

encode(self, val=None)

Encode data provided as an arguement or provided at initialization.

Args

val : any, optional Data for encoding. Defaults to None.

Returns

bytes : encoded data

Source code in pyben\classes.py
def encode(self, val=None):
    """
    Encode data provided as an arguement or provided at initialization.

    Args
    ----
    val : any, optional
        Data for encoding. Defaults to None.

    Returns
    -------
    `bytes` : encoded data

    """
    if val is None:
        val = self.data
    self.encoded = self._encode(val)
    return self.encoded

API helper functions for decoding and encoding data with bencode format.

Functions

  • bendecode
  • bendecode_dict
  • bendecode_int
  • bendecode_list
  • bendecode_str

  • benencode

  • bencode_bytes
  • bencode_dict
  • bencode_int
  • bencode_list
  • bencode_str

bencode_bytes(bits)

Encode bytes.

Args

bits : bytes Bytes treated as a byte-string literal.

Returns

bytes: Bencode encoded byte string literal.

Source code in pyben\bencode.py
def bencode_bytes(bits):
    """
    Encode bytes.

    Args
    ----
    bits : `bytes`
        Bytes treated as a byte-string literal.

    Returns
    -------
    `bytes`:
        Bencode encoded byte string literal.

    """
    size = str(len(bits)) + ":"
    return size.encode("utf-8") + bits

bencode_dict(dic)

Encode dictionary and contents.

Args

dic : dict Any dictionary containing items that can be bencoded.

Returns

bytes : Bencoded key, value pairs of data.

Source code in pyben\bencode.py
def bencode_dict(dic):
    """
    Encode dictionary and contents.

    Args
    ----
    dic : `dict`
        Any dictionary containing items that can be bencoded.

    Returns
    -------
    `bytes` :
        Bencoded key, value pairs of data.
    """
    result = b"d"

    for key, val in dic.items():
        result += b"".join([benencode(key), benencode(val)])

    return result + b"e"

bencode_int(i)

Encode integer type.

Args

i : int Number that needs encoding.

Returns

bytes : Bencoded Integer.

Source code in pyben\bencode.py
def bencode_int(i):
    """
    Encode integer type.

    Args
    ----
    i : `int`
        Number that needs encoding.

    Returns
    -------
    `bytes` :
        Bencoded Integer.

    """
    return ("i" + str(i) + "e").encode("utf-8")

bencode_list(elems)

Encode list and contents.

Args

elems : list List of items for bencoding.

Returns

bytes : Bencoded list and contents.

Source code in pyben\bencode.py
def bencode_list(elems):
    """
    Encode list and contents.

    Args
    ----
    elems : `list`
        List of items for bencoding.

    Returns
    -------
    `bytes` :
        Bencoded list and contents.

    """
    arr = bytearray("l", encoding="utf-8")

    for elem in elems:
        encoded = benencode(elem)
        arr.extend(encoded)

    arr.extend(b"e")
    return arr

bencode_str(txt)

Encode string literals.

Args

txt : str Any text string.

Returns

bytes : Bencoded string literal.

Source code in pyben\bencode.py
def bencode_str(txt):
    """
    Encode string literals.

    Args
    ----
    txt : `str`
        Any text string.

    Returns
    -------
    `bytes` :
        Bencoded string literal.

    """
    size = str(len(txt)) + ":"
    return size.encode("utf-8") + txt.encode("utf-8")

bendecode(bits)

Decode bencoded data.

Args

bits : bytes Bencode encoded data.

Raises

DecodeError : Malformed data.

Returns

any : Bencode decoded data.

Source code in pyben\bencode.py
def bendecode(bits):
    """
    Decode bencoded data.

    Args
    ----
    bits : `bytes`
        Bencode encoded data.

    Raises
    ------
    `DecodeError` :
        Malformed data.

    Returns
    -------
    any :
        Bencode decoded data.

    """
    if bits.startswith(b"i"):
        match, feed = bendecode_int(bits)
        return match, feed

    if chr(bits[0]).isdigit():
        match, feed = bendecode_str(bits)
        return match, feed

    if bits.startswith(b"l"):
        lst, feed = bendecode_list(bits)
        return lst, feed

    if bits.startswith(b"d"):
        dic, feed = bendecode_dict(bits)
        return dic, feed

    raise DecodeError(bits)

bendecode_dict(bits)

Decode dictionary and it's contents.

Args

bits : bytes Bencoded dictionary.

Returns

dict Decoded dictionary and contents

Source code in pyben\bencode.py
def bendecode_dict(bits):
    """
    Decode dictionary and it's contents.

    Args
    ----
    bits : `bytes`
        Bencoded dictionary.

    Returns
    -------
    `dict`
        Decoded dictionary and contents

    """
    dic, feed = {}, 1

    while not bits[feed:].startswith(b"e"):
        match1, rest = bendecode(bits[feed:])
        feed += rest
        match2, rest = bendecode(bits[feed:])
        feed += rest
        dic[match1] = match2

    feed += 1
    return dic, feed

bendecode_int(bits)

Decode digits.

Args

bits : bytes Bencoded intiger bytes

Returns

int : Decoded int value.

Source code in pyben\bencode.py
def bendecode_int(bits):
    """
    Decode digits.

    Args
    ----
    bits : `bytes`
        Bencoded intiger bytes

    Returns
    -------
    `int` :
        Decoded int value.

    """
    obj = re.match(br"i(-?\d+)e", bits)
    return int(obj.group(1)), obj.end()

bendecode_list(bits)

Decode list and list contents.

Args

bits : bytes Bencoded list.

Returns

list : Bencode decoded list and contents.

Source code in pyben\bencode.py
def bendecode_list(bits):
    """
    Decode list and list contents.

    Args
    ----
    bits : `bytes`
        Bencoded list.

    Returns
    -------
    `list` :
        Bencode decoded list and contents.

    """
    lst, feed = [], 1

    while not bits[feed:].startswith(b"e"):
        match, rest = bendecode(bits[feed:])
        lst.append(match)
        feed += rest

    feed += 1
    return lst, feed

bendecode_str(units)

Bendecode string types.

Args

bits : bytes Bencoded string.

Returns

str : Decoded data string.

Source code in pyben\bencode.py
def bendecode_str(units):
    """
    Bendecode string types.

    Args
    ----
    bits : `bytes`
        Bencoded string.

    Returns
    -------
    `str` :
        Decoded data string.

    """
    match = re.match(br"(\d+):", units)
    word_len, start = int(match.groups()[0]), match.span()[1]
    end = start + word_len
    text = units[start:end]

    try:
        text = text.decode("utf-8")

    except UnicodeDecodeError:
        pass

    return text, end

benencode(val)

Encode data with bencoding.

Args

val : any Data for encoding.

Raises

EncodeError : Cannot interpret data.

Returns

bytes : Bencoded data.

Source code in pyben\bencode.py
def benencode(val):
    """
    Encode data with bencoding.

    Args
    ----
    val : any
        Data for encoding.

    Raises
    ------
    `EncodeError` :
        Cannot interpret data.

    Returns
    -------
    `bytes` :
        Bencoded data.

    """
    if isinstance(val, str):
        return bencode_str(val)

    if isinstance(val, int):
        return bencode_int(val)

    if isinstance(val, list):
        return bencode_list(val)

    if isinstance(val, dict):
        return bencode_dict(val)

    if hasattr(val, "hex"):
        return bencode_bytes(val)

    if isinstance(val, tuple):
        return bencode_list(list(val))

    raise EncodeError(val)

Exceptions used throughout the PyBen Package/Library.

DecodeError (Exception)

Error occured during decode process.

Raised when attempting to decode an incompatible bytearray. Mostly it indicates the object is a hash digest and should remian as a bytes object.


val : any Value that cause the exception

__init__(self, val=None) special

Construct Exception DecodeError.

Source code in pyben\exceptions.py
def __init__(self, val=None):
    """Construct Exception DecodeError."""
    msg = f"Decoder is unable to interpret {type(val)} type = {str(val)}"
    super().__init__(msg)

EncodeError (Exception)

Error occured during encoding process.

Raised when attempting to bencode encode an incompatible data type into bencode format. Bencode accepts lists, dicts, strings, integers, and bytes.


val : any Value that cause the exception

__init__(self, val=None) special

Construct Exception EncodeError.

Source code in pyben\exceptions.py
def __init__(self, val=None):
    """Construct Exception EncodeError."""
    msg = f"Encoder is unable to interpret {type(val)} type = {str(val)}"
    super().__init__(msg)

FilePathError (Exception)

Bad path error.

Generally raised when the file at the path specified does not exist.


val : any Value that cause the exception

__init__(self, obj=None) special

Construct Exception Subclass FilePathError.

Source code in pyben\exceptions.py
def __init__(self, obj=None):
    """Construct Exception Subclass FilePathError."""
    msg = f"{str(obj)} doesn't exist or is unavailable."
    super().__init__(msg)