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
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
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
@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
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 |
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
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
¶
comic_id_url(comic_id: int) -> str
¶
_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
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
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
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
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
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
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
@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