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)