Skip to content

Models

Attachment

Bases: JsonStruct

Represents an attachment with its content and name.

name instance-attribute

name: str

The name of the attachment.

content instance-attribute

content: bytes

The binary content of the attachment.

from_json classmethod

from_json(data: str) -> Self

Create an instance of this class from a JSON string.

Parameters:

Name Type Description Default
data str

JSON string representing the Paste instance.

required

Returns:

Type Description
Self
Source code in src/privatebin/_models.py
@classmethod
def from_json(cls, data: str, /) -> Self:
    """
    Create an instance of this class from a JSON string.

    Parameters
    ----------
    data : str
        JSON string representing the Paste instance.

    Returns
    -------
    Self

    """
    return msgspec.json.decode(data, type=cls)

to_json

to_json(*, indent: int = 2) -> str

Serialize this instance into a JSON string.

Parameters:

Name Type Description Default
indent int

Number of spaces for indentation. Set to 0 for a single line with spacing, or negative to minimize size by removing extra whitespace.

2

Returns:

Type Description
str

JSON string representing the Paste.

Source code in src/privatebin/_models.py
def to_json(self, *, indent: int = 2) -> str:
    """
    Serialize this instance into a JSON string.

    Parameters
    ----------
    indent : int, optional
        Number of spaces for indentation.
        Set to 0 for a single line with spacing,
        or negative to minimize size by removing extra whitespace.

    Returns
    -------
    str
        JSON string representing the Paste.

    """
    jsonified = msgspec.json.encode(self)
    return msgspec.json.format(jsonified, indent=indent).decode()

from_file classmethod

from_file(
    file: str | PathLike[str], *, name: str | None = None
) -> Self

Create an Attachment instance from a file path.

If a name is not provided, the filename from the path is used as the attachment name.

Parameters:

Name Type Description Default
file str | PathLike[str]

Path to the file from which to create the attachment.

required
name str | None

The desired name for the attachment. If None, the filename from file is used.

None

Returns:

Type Description
Self

Raises:

Type Description
FileNotFoundError

If the provided file path does not exist or is not a file.

Source code in src/privatebin/_models.py
@classmethod
def from_file(cls, file: str | PathLike[str], *, name: str | None = None) -> Self:
    """
    Create an `Attachment` instance from a file path.

    If a name is not provided, the filename from the path is used as the attachment name.

    Parameters
    ----------
    file : str | PathLike[str]
        Path to the file from which to create the attachment.
    name : str | None, optional
        The desired name for the attachment. If `None`, the filename from `file` is used.

    Returns
    -------
    Self

    Raises
    ------
    FileNotFoundError
        If the provided `file` path does not exist or is not a file.

    """
    file = Path(file).expanduser().resolve()

    if not file.is_file():
        raise FileNotFoundError(file)

    filename = name if name else file.name
    content = file.read_bytes()

    return cls(content=content, name=filename)

from_data_url classmethod

from_data_url(*, url: str, name: str) -> Self

Create an Attachment from a data URL.

Parameters:

Name Type Description Default
url str

Attachment content as a data URL.

required
name str

The desired name for the attachment.

required

Returns:

Type Description
Self

Raises:

Type Description
ValueError

If the provided url is not a data URL.

Source code in src/privatebin/_models.py
@classmethod
def from_data_url(cls, *, url: str, name: str) -> Self:
    """
    Create an Attachment from a [data URL][Data URL].

    [Data URL]: https://developer.mozilla.org/en-US/docs/Web/URI/Reference/Schemes/data

    Parameters
    ----------
    url : str
        Attachment content as a data URL.
    name : str
        The desired name for the attachment.

    Returns
    -------
    Self

    Raises
    ------
    ValueError
        If the provided `url` is not a data URL.

    """
    # https://regex101.com/r/Wiu431/1
    pattern = r"^data:(?P<mimetype>.+);base64,(?P<data>.+)$"
    match = re.fullmatch(pattern, url)

    if match is None:
        truncated = url[:50] + "... (TRUNCATED)" if len(url) > 50 else url  # noqa: PLR2004
        msg = (
            "Paste has an invalid or unsupported attachment. "
            f"Expected a data URL: 'data:<mimetype>;base64,<data>', got: {truncated!r}"
        )
        raise ValueError(msg)

    data = match.group("data")
    content = base64.b64decode(data)

    return cls(content=content, name=name)

to_data_url

to_data_url() -> str

Convert the Attachment's binary content to a data URL.

Returns:

Type Description
str

A data URL representing the attachment content.

Source code in src/privatebin/_models.py
def to_data_url(self) -> str:
    """
    Convert the Attachment's binary content to a [data URL][Data URL].

    [Data URL]: https://developer.mozilla.org/en-US/docs/Web/URI/Reference/Schemes/data

    Returns
    -------
    str
        A data URL representing the attachment content.

    """
    encoded = base64.b64encode(self.content).decode()
    mimetype = guess_mime_type(self.name)
    return f"data:{mimetype};base64,{encoded}"

Paste

Bases: JsonStruct

Represents a PrivateBin paste.

id instance-attribute

id: str

Unique identifier for the paste.

text instance-attribute

text: str

The decrypted text content of the paste.

attachment instance-attribute

attachment: Attachment | None

Attachment associated with the paste, if any.

formatter instance-attribute

formatter: Formatter

Formatting option applied to the paste content.

open_discussion instance-attribute

open_discussion: bool

Indicates if open discussions are enabled for this paste.

burn_after_reading instance-attribute

burn_after_reading: bool

Indicates if the paste is set to be burned after the first read.

time_to_live instance-attribute

time_to_live: timedelta | None

Time duration for which the paste is set to be stored, if any.

from_json classmethod

from_json(data: str) -> Self

Create an instance of this class from a JSON string.

Parameters:

Name Type Description Default
data str

JSON string representing the Paste instance.

required

Returns:

Type Description
Self
Source code in src/privatebin/_models.py
@classmethod
def from_json(cls, data: str, /) -> Self:
    """
    Create an instance of this class from a JSON string.

    Parameters
    ----------
    data : str
        JSON string representing the Paste instance.

    Returns
    -------
    Self

    """
    return msgspec.json.decode(data, type=cls)

to_json

to_json(*, indent: int = 2) -> str

Serialize this instance into a JSON string.

Parameters:

Name Type Description Default
indent int

Number of spaces for indentation. Set to 0 for a single line with spacing, or negative to minimize size by removing extra whitespace.

2

Returns:

Type Description
str

JSON string representing the Paste.

Source code in src/privatebin/_models.py
def to_json(self, *, indent: int = 2) -> str:
    """
    Serialize this instance into a JSON string.

    Parameters
    ----------
    indent : int, optional
        Number of spaces for indentation.
        Set to 0 for a single line with spacing,
        or negative to minimize size by removing extra whitespace.

    Returns
    -------
    str
        JSON string representing the Paste.

    """
    jsonified = msgspec.json.encode(self)
    return msgspec.json.format(jsonified, indent=indent).decode()

PasteReceipt

Bases: JsonStruct

Represents the result of a paste creation.

url instance-attribute

The URL of the newly created paste.

delete_token instance-attribute

delete_token: str

The token required to delete the paste.

from_json classmethod

from_json(data: str) -> Self

Create an instance of this class from a JSON string.

Parameters:

Name Type Description Default
data str

JSON string representing the Paste instance.

required

Returns:

Type Description
Self
Source code in src/privatebin/_models.py
@classmethod
def from_json(cls, data: str, /) -> Self:
    """
    Create an instance of this class from a JSON string.

    Parameters
    ----------
    data : str
        JSON string representing the Paste instance.

    Returns
    -------
    Self

    """
    return msgspec.json.decode(data, type=cls)

to_json

to_json(*, indent: int = 2) -> str

Serialize this instance into a JSON string.

Parameters:

Name Type Description Default
indent int

Number of spaces for indentation. Set to 0 for a single line with spacing, or negative to minimize size by removing extra whitespace.

2

Returns:

Type Description
str

JSON string representing the Paste.

Source code in src/privatebin/_models.py
def to_json(self, *, indent: int = 2) -> str:
    """
    Serialize this instance into a JSON string.

    Parameters
    ----------
    indent : int, optional
        Number of spaces for indentation.
        Set to 0 for a single line with spacing,
        or negative to minimize size by removing extra whitespace.

    Returns
    -------
    str
        JSON string representing the Paste.

    """
    jsonified = msgspec.json.encode(self)
    return msgspec.json.format(jsonified, indent=indent).decode()

PrivateBinUrl

Bases: JsonStruct

Represents a PrivateBin URL.

server instance-attribute

server: str

The base server URL of the PrivateBin instance.

id instance-attribute

id: str

The unique paste ID. This identifies the specific paste on the server.

passphrase instance-attribute

passphrase: str

The decryption passphrase. This is needed to decrypt and view encrypted pastes.

from_json classmethod

from_json(data: str) -> Self

Create an instance of this class from a JSON string.

Parameters:

Name Type Description Default
data str

JSON string representing the Paste instance.

required

Returns:

Type Description
Self
Source code in src/privatebin/_models.py
@classmethod
def from_json(cls, data: str, /) -> Self:
    """
    Create an instance of this class from a JSON string.

    Parameters
    ----------
    data : str
        JSON string representing the Paste instance.

    Returns
    -------
    Self

    """
    return msgspec.json.decode(data, type=cls)

to_json

to_json(*, indent: int = 2) -> str

Serialize this instance into a JSON string.

Parameters:

Name Type Description Default
indent int

Number of spaces for indentation. Set to 0 for a single line with spacing, or negative to minimize size by removing extra whitespace.

2

Returns:

Type Description
str

JSON string representing the Paste.

Source code in src/privatebin/_models.py
def to_json(self, *, indent: int = 2) -> str:
    """
    Serialize this instance into a JSON string.

    Parameters
    ----------
    indent : int, optional
        Number of spaces for indentation.
        Set to 0 for a single line with spacing,
        or negative to minimize size by removing extra whitespace.

    Returns
    -------
    str
        JSON string representing the Paste.

    """
    jsonified = msgspec.json.encode(self)
    return msgspec.json.format(jsonified, indent=indent).decode()

unmask

unmask() -> str

Explicitly convert this instance into a complete, unmasked URL string.

This method behaves differently from implicit Python string conversions like print(url), or f-strings (f"{url}").

  • unmask() returns the full, unmasked URL with the sensitive passphrase.
  • Implicit conversions (print(), f-strings, etc.) return a masked URL for safety.

Call unmask() when you explicitly need the full, working URL, for example, to:

  • Open the URL in a browser.
  • Pass the URL to a function that requires the unmasked passphrase.

Returns:

Type Description
str

The full, unmasked PrivateBin URL.

Examples:

>>> url = PrivateBinUrl(server="https://example.privatebin.com/", id="pasteid", passphrase="secret")
>>> print(url)  # Implicit string conversion - masked URL
'https://example.privatebin.com/?pasteid#********'
>>> f"{url}"  # Implicit string conversion in f-string - masked URL
'https://example.privatebin.com/?pasteid#********'
>>> url.unmask()
'https://example.privatebin.com/?pasteid#secret'
Source code in src/privatebin/_models.py
def unmask(self) -> str:
    """
    Explicitly convert this instance into a complete, unmasked URL string.

    This method behaves differently from implicit Python string conversions
    like `print(url)`, or f-strings (`f"{url}"`).

    -  `unmask()` returns the full, unmasked URL with the sensitive passphrase.
    -  Implicit conversions (`print()`, f-strings, etc.) return a masked URL for safety.

    Call `unmask()` when you explicitly need the full, working URL, for example, to:

    -  Open the URL in a browser.
    -  Pass the URL to a function that requires the unmasked passphrase.

    Returns
    -------
    str
        The full, unmasked PrivateBin URL.

    Examples
    --------
    >>> url = PrivateBinUrl(server="https://example.privatebin.com/", id="pasteid", passphrase="secret")
    >>> print(url)  # Implicit string conversion - masked URL
    'https://example.privatebin.com/?pasteid#********'
    >>> f"{url}"  # Implicit string conversion in f-string - masked URL
    'https://example.privatebin.com/?pasteid#********'
    >>> url.unmask()
    'https://example.privatebin.com/?pasteid#secret'

    """
    return urljoin(self.server, f"/?{self.id}#{self.passphrase}")

parse classmethod

parse(url: str | PrivateBinUrl | PasteReceipt) -> Self

Parse a URL-like object into a PrivateBinUrl instance.

Parameters:

Name Type Description Default
url str | PrivateBinUrl | PasteReceipt

The URL-like object to parse.

required

Returns:

Type Description
Self

Raises:

Type Description
ValueError

If the provided 'url' string is not in the expected format.

TypeError

If the provided 'url' is not in the expected type.

Source code in src/privatebin/_models.py
@classmethod
def parse(cls, url: str | PrivateBinUrl | PasteReceipt, /) -> Self:
    """
    Parse a URL-like object into a `PrivateBinUrl` instance.

    Parameters
    ----------
    url : str | PrivateBinUrl | PasteReceipt
        The URL-like object to parse.

    Returns
    -------
    Self

    Raises
    ------
    ValueError
        If the provided 'url' string is not in the expected format.
    TypeError
        If the provided 'url' is not in the expected type.

    """
    match url:
        case str():
            try:
                server, id_passphrase = url.strip().split("?")
                id, passphrase = id_passphrase.split("#")

                # The leading hyphen is a visual cue for "burn-after-reading" pastes.
                # This code removes it because it's not part of the actual passphrase
                # and would cause decryption to fail. Removing it also ensures that
                # pastes with and without the hyphen are treated as identical.
                passphrase = passphrase.removeprefix("-")

                return cls(server=server, id=id, passphrase=passphrase)
            except ValueError:
                msg = (
                    "Invalid PrivateBin URL format. "
                    "URL should be like: https://examplebin.net/?pasteid#passphrase. "
                    f"Got: {url!r}"
                )
                raise ValueError(msg) from None
        case PrivateBinUrl():
            return cls(server=url.server, id=url.id, passphrase=url.passphrase)
        case PasteReceipt():
            url = url.url
            return cls(server=url.server, id=url.id, passphrase=url.passphrase)
        case _:
            msg = f"Parameter 'url' expected 'str', 'PrivateBinUrl', or 'PasteReceipt', but got {type(url).__name__!r}."
            raise TypeError(msg)