Skip to content

tux.wrappers.xkcd

Classes:

Name Description
HttpError
Comic

A class representing an xkcd comic.

Client

Classes

HttpError(status_code: int, reason: str)

Bases: Exception

Initialize the HttpError.

Parameters:

Name Type Description Default
status_code int

The status code of the error.

required
reason str

The reason of the error.

required
Source code in tux/wrappers/xkcd.py
Python
def __init__(self, status_code: int, reason: str) -> None:
    """
    Initialize the HttpError.

    Parameters
    ----------
    status_code : int
        The status code of the error.
    reason : str
        The reason of the error.
    """
    self.status_code = status_code
    self.reason = reason
    super().__init__(f"HTTP Error {status_code}: {reason}")

Functions

Comic(xkcd_dict: dict[str, Any], raw_image: bytes | None = None, comic_url: str | None = None, explanation_url: str | None = None)

A class representing an xkcd comic.

Methods:

Name Description
update_raw_image

Update the raw image of the comic.

__repr__

Return the representation of the comic.

Source code in tux/wrappers/xkcd.py
Python
def __init__(
    self,
    xkcd_dict: dict[str, Any],
    raw_image: bytes | None = None,
    comic_url: str | None = None,
    explanation_url: str | None = None,
) -> None:
    self.id: int | None = xkcd_dict.get("num")
    self.date: datetime.date | None = self._determine_date(xkcd_dict)
    self.title: str | None = xkcd_dict.get("safe_title")
    self.description: str | None = xkcd_dict.get("alt")
    self.transcript: str | None = xkcd_dict.get("transcript")
    self.image: bytes | None = raw_image
    self.image_extension: str | None = self._determine_image_extension()
    self.image_url: str | None = xkcd_dict.get("img")
    self.comic_url: str | None = comic_url
    self.explanation_url: str | None = explanation_url

Functions

_determine_date(xkcd_dict: dict[str, Any]) -> datetime.date | None staticmethod

Determine the date of the comic.

Parameters:

Name Type Description Default
xkcd_dict dict[str, Any]

The dictionary containing the comic data.

required

Returns:

Type Description
date | None

The date of the comic.

Source code in tux/wrappers/xkcd.py
Python
@staticmethod
def _determine_date(xkcd_dict: dict[str, Any]) -> datetime.date | None:
    """
    Determine the date of the comic.

    Parameters
    ----------
    xkcd_dict : dict[str, Any]
        The dictionary containing the comic data.

    Returns
    -------
    datetime.date | None
        The date of the comic.
    """

    try:
        return datetime.date(
            int(xkcd_dict["year"]),
            int(xkcd_dict["month"]),
            int(xkcd_dict["day"]),
        )

    except (KeyError, ValueError):
        return None
_determine_image_extension() -> str | None

Determine the image extension of the comic.

Returns:

Type Description
str | None

The extension of the image.

Source code in tux/wrappers/xkcd.py
Python
def _determine_image_extension(self) -> str | None:
    """
    Determine the image extension of the comic.

    Returns
    -------
    str | None
        The extension of the image.
    """

    if self.image:
        try:
            image = Image.open(BytesIO(self.image))
            return f".{image.format.lower()}" if image.format else None
        except (OSError, UnidentifiedImageError):
            return None
    return None
update_raw_image(raw_image: bytes) -> None

Update the raw image of the comic.

Parameters:

Name Type Description Default
raw_image bytes

The raw image data.

required
Source code in tux/wrappers/xkcd.py
Python
def update_raw_image(self, raw_image: bytes) -> None:
    """
    Update the raw image of the comic.

    Parameters
    ----------
    raw_image : bytes
        The raw image data.
    """

    self.image = raw_image
    self.image_extension = self._determine_image_extension()
__repr__() -> str

Return the representation of the comic.

Returns:

Type Description
str

The representation of the comic.

Source code in tux/wrappers/xkcd.py
Python
def __repr__(self) -> str:
    """
    Return the representation of the comic.

    Returns
    -------
    str
        The representation of the comic.
    """
    return f"Comic({self.title})"

Client(api_url: str = 'https://xkcd.com', explanation_wiki_url: str = 'https://www.explainxkcd.com/wiki/index.php/')

Initialize the Client.

Parameters:

Name Type Description Default
api_url str

The URL of the xkcd API, by default "https://xkcd.com"

'https://xkcd.com'
explanation_wiki_url str

The URL of the xkcd explanation wiki, by default "https://www.explainxkcd.com/wiki/index.php/"

'https://www.explainxkcd.com/wiki/index.php/'

Methods:

Name Description
latest_comic_url

Get the URL for the latest comic.

comic_id_url

Get the URL for a specific comic ID.

get_latest_comic

Get the latest xkcd comic.

get_comic

Get a specific xkcd comic.

get_random_comic

Get a random xkcd comic.

__repr__

Return the representation of the client.

Source code in tux/wrappers/xkcd.py
Python
def __init__(
    self,
    api_url: str = "https://xkcd.com",
    explanation_wiki_url: str = "https://www.explainxkcd.com/wiki/index.php/",
) -> None:
    """
    Initialize the Client.

    Parameters
    ----------
    api_url : str, optional
        The URL of the xkcd API, by default "https://xkcd.com"
    explanation_wiki_url : str, optional
        The URL of the xkcd explanation wiki, by default "https://www.explainxkcd.com/wiki/index.php/"
    """

    self._api_url = api_url
    self._explanation_wiki_url = explanation_wiki_url

Functions

latest_comic_url() -> str

Get the URL for the latest comic.

Returns:

Type Description
str

The URL for the latest comic.

Source code in tux/wrappers/xkcd.py
Python
def latest_comic_url(self) -> str:
    """
    Get the URL for the latest comic.

    Returns
    -------
    str
        The URL for the latest comic.
    """

    return f"{self._api_url}/info.0.json"
comic_id_url(comic_id: int) -> str

Get the URL for a specific comic ID.

Parameters:

Name Type Description Default
comic_id int

The ID of the comic.

required

Returns:

Type Description
str

The URL for the specific comic ID.

Source code in tux/wrappers/xkcd.py
Python
def comic_id_url(self, comic_id: int) -> str:
    """
    Get the URL for a specific comic ID.

    Parameters
    ----------
    comic_id : int
        The ID of the comic.

    Returns
    -------
    str
        The URL for the specific comic ID.
    """

    return f"{self._api_url}/{comic_id}/info.0.json"
_parse_response(response_text: str) -> Comic

Parse the response text into a Comic object.

Parameters:

Name Type Description Default
response_text str

The response text to parse.

required

Returns:

Type Description
Comic

The parsed comic object.

Source code in tux/wrappers/xkcd.py
Python
def _parse_response(self, response_text: str) -> Comic:
    """
    Parse the response text into a Comic object.

    Parameters
    ----------
    response_text : str
        The response text to parse.

    Returns
    -------
    Comic
        The parsed comic object.
    """

    response_dict: dict[str, Any] = json.loads(response_text)
    comic_url: str = f"{self._api_url}/{response_dict['num']}/"
    explanation_url: str = f"{self._explanation_wiki_url}{response_dict['num']}"

    return Comic(response_dict, comic_url=comic_url, explanation_url=explanation_url)
_fetch_comic(comic_id: int, raw_comic_image: bool) -> Comic

Fetch a comic from the xkcd API.

Parameters:

Name Type Description Default
comic_id int

The ID of the comic to fetch.

required
raw_comic_image bool

Whether to fetch the raw image data.

required

Returns:

Type Description
Comic

The fetched comic.

Source code in tux/wrappers/xkcd.py
Python
def _fetch_comic(self, comic_id: int, raw_comic_image: bool) -> Comic:
    """
    Fetch a comic from the xkcd API.

    Parameters
    ----------
    comic_id : int
        The ID of the comic to fetch.
    raw_comic_image : bool
        Whether to fetch the raw image data.

    Returns
    -------
    Comic
        The fetched comic.
    """

    comic = self._parse_response(self._request_comic(comic_id))

    if raw_comic_image:
        raw_image = self._request_raw_image(comic.image_url)
        comic.update_raw_image(raw_image)

    return comic
get_latest_comic(raw_comic_image: bool = False) -> Comic

Get the latest xkcd comic.

Parameters:

Name Type Description Default
raw_comic_image bool

Whether to fetch the raw image data, by default False

False

Returns:

Type Description
Comic

The latest xkcd comic.

Source code in tux/wrappers/xkcd.py
Python
def get_latest_comic(self, raw_comic_image: bool = False) -> Comic:
    """
    Get the latest xkcd comic.

    Parameters
    ----------
    raw_comic_image : bool, optional
        Whether to fetch the raw image data, by default False

    Returns
    -------
    Comic
        The latest xkcd comic.
    """

    return self._fetch_comic(0, raw_comic_image)
get_comic(comic_id: int, raw_comic_image: bool = False) -> Comic

Get a specific xkcd comic.

Parameters:

Name Type Description Default
comic_id int

The ID of the comic to fetch.

required
raw_comic_image bool

Whether to fetch the raw image data, by default False

False

Returns:

Type Description
Comic

The fetched xkcd comic.

Source code in tux/wrappers/xkcd.py
Python
def get_comic(self, comic_id: int, raw_comic_image: bool = False) -> Comic:
    """
    Get a specific xkcd comic.

    Parameters
    ----------
    comic_id : int
        The ID of the comic to fetch.
    raw_comic_image : bool, optional
        Whether to fetch the raw image data, by default False

    Returns
    -------
    Comic
        The fetched xkcd comic.
    """

    return self._fetch_comic(comic_id, raw_comic_image)
get_random_comic(raw_comic_image: bool = False) -> Comic

Get a random xkcd comic.

Parameters:

Name Type Description Default
raw_comic_image bool

Whether to fetch the raw image data, by default False

False

Returns:

Type Description
Comic

The random xkcd comic.

Source code in tux/wrappers/xkcd.py
Python
def get_random_comic(self, raw_comic_image: bool = False) -> Comic:
    """
    Get a random xkcd comic.

    Parameters
    ----------
    raw_comic_image : bool, optional
        Whether to fetch the raw image data, by default False

    Returns
    -------
    Comic
        The random xkcd comic.
    """

    latest_comic_id: int = self._parse_response(self._request_comic(0)).id or 0
    random_id: int = random.randint(1, latest_comic_id)

    return self._fetch_comic(random_id, raw_comic_image)
_request_comic(comic_id: int) -> str

Request the comic data from the xkcd API.

Parameters:

Name Type Description Default
comic_id int

The ID of the comic to fetch.

required

Returns:

Type Description
str

The response text.

Raises:

Type Description
HttpError

If the request fails.

Source code in tux/wrappers/xkcd.py
Python
def _request_comic(self, comic_id: int) -> str:
    """
    Request the comic data from the xkcd API.

    Parameters
    ----------
    comic_id : int
        The ID of the comic to fetch.

    Returns
    -------
    str
        The response text.

    Raises
    ------
    HttpError
        If the request fails.
    """

    comic_url = self.latest_comic_url() if comic_id <= 0 else self.comic_id_url(comic_id)

    try:
        response = httpx.get(comic_url)
        response.raise_for_status()

    except httpx.HTTPStatusError as exc:
        raise HttpError(exc.response.status_code, exc.response.reason_phrase) from exc

    return response.text
_request_raw_image(raw_image_url: str | None) -> bytes staticmethod

Request the raw image data from the xkcd API.

Parameters:

Name Type Description Default
raw_image_url str | None

The URL of the raw image data.

required

Returns:

Type Description
bytes

The raw image data.

Raises:

Type Description
HttpError

If the request fails.

Source code in tux/wrappers/xkcd.py
Python
@staticmethod
def _request_raw_image(raw_image_url: str | None) -> bytes:
    """
    Request the raw image data from the xkcd API.

    Parameters
    ----------
    raw_image_url : str | None
        The URL of the raw image data.

    Returns
    -------
    bytes
        The raw image data.

    Raises
    ------
    HttpError
        If the request fails.
    """

    if not raw_image_url:
        raise HttpError(404, "Image URL not found")

    try:
        response = httpx.get(raw_image_url)
        response.raise_for_status()

    except httpx.HTTPStatusError as exc:
        raise HttpError(exc.response.status_code, exc.response.reason_phrase) from exc

    return response.content
__repr__() -> str

Return the representation of the client.

Returns:

Type Description
str

The representation of the client.

Source code in tux/wrappers/xkcd.py
Python
def __repr__(self) -> str:
    """
    Return the representation of the client.

    Returns
    -------
    str
        The representation of the client.
    """
    return "Client()"