Skip to content

Commit

Permalink
Feature: Add method docstrings to basically everything (#33)
Browse files Browse the repository at this point in the history
  • Loading branch information
stumpylog authored Sep 30, 2024
1 parent 601a6dd commit 2649b27
Show file tree
Hide file tree
Showing 13 changed files with 699 additions and 90 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added

- All routes now return a stronger typed response than just an `httpx.Response` ([#23](https://github.com/stumpylog/gotenberg-client/pull/23))
- All public methods now include docstrings ([#33](https://github.com/stumpylog/gotenberg-client/pull/33))

### Changed

Expand Down
10 changes: 9 additions & 1 deletion src/gotenberg_client/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,15 @@
from gotenberg_client._client import GotenbergClient
from gotenberg_client._errors import BaseClientError
from gotenberg_client._errors import CannotExtractHereError
from gotenberg_client._errors import MaxRetriesExceededError
from gotenberg_client.responses import SingleFileResponse
from gotenberg_client.responses import ZipFileResponse

__all__ = ["GotenbergClient", "SingleFileResponse", "ZipFileResponse", "BaseClientError", "CannotExtractHereError"]
__all__ = [
"GotenbergClient",
"SingleFileResponse",
"ZipFileResponse",
"BaseClientError",
"CannotExtractHereError",
"MaxRetriesExceededError",
]
68 changes: 63 additions & 5 deletions src/gotenberg_client/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
from httpx import Response
from httpx._types import RequestFiles

from gotenberg_client._errors import MaxRetriesExceededError
from gotenberg_client._errors import UnreachableCodeError
from gotenberg_client._types import Self
from gotenberg_client._types import WaitTimeType
from gotenberg_client._utils import guess_mime_type
Expand All @@ -26,10 +28,6 @@
logger = logging.getLogger(__name__)


class UnreachableCodeError(Exception):
pass


class PdfFormatMixin:
"""
https://gotenberg.dev/docs/routes#pdfa-chromium
Expand Down Expand Up @@ -156,7 +154,7 @@ def _base_run_with_retry(

# Don't do the extra waiting, return right away
if current_retry_count >= max_retry_count:
raise
raise MaxRetriesExceededError(response=e.response) from e

except Exception as e: # pragma: no cover
logger.warning(f"Unexpected error: {e}", stacklevel=1)
Expand Down Expand Up @@ -226,6 +224,17 @@ def output_name(self, filename: str) -> Self:

class BaseSingleFileResponseRoute(_BaseRoute):
def run(self) -> SingleFileResponse:
"""
Execute the API request to Gotenberg.
This method sends the configured request to the Gotenberg service and returns the response.
Returns:
SingleFileResponse: An object containing the response from the Gotenberg API
Raises:
httpx.Error: Any errors from httpx will be raised
"""
response = super()._base_run()

return SingleFileResponse(response.status_code, response.headers, response.content)
Expand All @@ -237,6 +246,25 @@ def run_with_retry(
initial_retry_wait: WaitTimeType = 5,
retry_scale: WaitTimeType = 2,
) -> SingleFileResponse:
"""
Execute the API request with a retry mechanism.
This method attempts to run the API request and automatically retries in case of failures.
It uses an exponential backoff strategy for retries.
Args:
max_retry_count (int, optional): The maximum number of retry attempts. Defaults to 5.
initial_retry_wait (WaitTimeType, optional): The initial wait time between retries in seconds.
Defaults to 5. Can be int or float.
retry_scale (WaitTimeType, optional): The scale factor for the exponential backoff.
Defaults to 2. Can be int or float.
Returns:
SingleFileResponse: The response object containing the result of the API call.
Raises:
MaxRetriesExceededError: If the maximum number of retries is exceeded without a successful response.
"""
response = super()._base_run_with_retry(
max_retry_count=max_retry_count,
initial_retry_wait=initial_retry_wait,
Expand All @@ -248,6 +276,17 @@ def run_with_retry(

class BaseZipFileResponseRoute(_BaseRoute):
def run(self) -> ZipFileResponse: # pragma: no cover
"""
Execute the API request to Gotenberg.
This method sends the configured request to the Gotenberg service and returns the response.
Returns:
ZipFileResponse: The zipped response with the files
Raises:
httpx.Error: Any errors from httpx will be raised
"""
response = super()._base_run()

return ZipFileResponse(response.status_code, response.headers, response.content)
Expand All @@ -259,6 +298,25 @@ def run_with_retry(
initial_retry_wait: WaitTimeType = 5,
retry_scale: WaitTimeType = 2,
) -> ZipFileResponse:
"""
Execute the API request with a retry mechanism.
This method attempts to run the API request and automatically retries in case of failures.
It uses an exponential backoff strategy for retries.
Args:
max_retry_count (int, optional): The maximum number of retry attempts. Defaults to 5.
initial_retry_wait (WaitTimeType, optional): The initial wait time between retries in seconds.
Defaults to 5. Can be int or float.
retry_scale (WaitTimeType, optional): The scale factor for the exponential backoff.
Defaults to 2. Can be int or float.
Returns:
ZipFileResponse: The zipped response with the files
Raises:
MaxRetriesExceededError: If the maximum number of retries is exceeded without a successful response.
"""
response = super()._base_run_with_retry(
max_retry_count=max_retry_count,
initial_retry_wait=initial_retry_wait,
Expand Down
71 changes: 64 additions & 7 deletions src/gotenberg_client/_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,18 @@

class GotenbergClient:
"""
The user's primary interface to the Gotenberg instance
The user's primary interface to the Gotenberg instance.
This class provides methods to configure and interact with a Gotenberg service,
including setting up API endpoints for various Gotenberg features and managing
webhook configurations.
Attributes:
chromium (ChromiumApi): Interface for Chromium-related operations.
libre_office (LibreOfficeApi): Interface for LibreOffice-related operations.
pdf_a (PdfAApi): Interface for PDF/A-related operations.
merge (MergeApi): Interface for PDF merging operations.
health (HealthCheckApi): Interface for health check operations.
"""

def __init__(
Expand All @@ -31,6 +42,15 @@ def __init__(
log_level: int = logging.ERROR,
http2: bool = True,
):
"""
Initialize a new GotenbergClient instance.
Args:
host (str): The base URL of the Gotenberg service.
timeout (float, optional): The timeout for API requests in seconds. Defaults to 30.0.
log_level (int, optional): The logging level for httpx and httpcore. Defaults to logging.ERROR.
http2 (bool, optional): Whether to use HTTP/2. Defaults to True.
"""
# Configure the client
self._client = Client(base_url=host, timeout=timeout, http2=http2)

Expand All @@ -47,46 +67,73 @@ def __init__(

def add_headers(self, header: Dict[str, str]) -> None:
"""
Updates the httpx Client headers with the given values
Update the httpx Client headers with the given values.
Args:
header (Dict[str, str]): A dictionary of header names and values to add.
"""
self._client.headers.update(header)

def add_webhook_url(self, url: str) -> None:
"""
Adds the webhook URL to the headers
Add the webhook URL to the headers.
Args:
url (str): The URL to be used as the webhook endpoint.
"""
self.add_headers({"Gotenberg-Webhook-Url": url})

def add_error_webhook_url(self, url: str) -> None:
"""
Adds the webhook error URL to the headers
Add the webhook error URL to the headers.
Args:
url (str): The URL to be used as the error webhook endpoint.
"""
self.add_headers({"Gotenberg-Webhook-Error-Url": url})

def set_webhook_http_method(self, method: HttpMethodsType = "PUT") -> None:
"""
Sets the HTTP method Gotenberg will use to call the hooks
Set the HTTP method Gotenberg will use to call the webhooks.
Args:
method (HttpMethodsType, optional): The HTTP method to use. Defaults to "PUT".
"""
self.add_headers({"Gotenberg-Webhook-Method": method})

def set_error_webhook_http_method(self, method: HttpMethodsType = "PUT") -> None:
"""
Sets the HTTP method Gotenberg will use to call the hooks
Set the HTTP method Gotenberg will use to call the error webhooks.
Args:
method (HttpMethodsType, optional): The HTTP method to use. Defaults to "PUT".
"""
self.add_headers({"Gotenberg-Webhook-Error-Method": method})

def set_webhook_extra_headers(self, extra_headers: Dict[str, str]) -> None:
"""
Sets the HTTP method Gotenberg will use to call the hooks
Set additional HTTP headers for Gotenberg to use when calling webhooks.
Args:
extra_headers (Dict[str, str]): A dictionary of additional headers to include in webhook calls.
"""
from json import dumps

self.add_headers({"Gotenberg-Webhook-Extra-Http-Headers": dumps(extra_headers)})

def __enter__(self) -> Self:
"""
Enter the runtime context related to this object.
Returns:
Self: The instance itself.
"""
return self

def close(self) -> None:
"""
Close the underlying HTTP client connection.
"""
self._client.close()

def __exit__(
Expand All @@ -95,4 +142,14 @@ def __exit__(
exc_val: Optional[BaseException],
exc_tb: Optional[TracebackType],
) -> None:
"""
Exit the runtime context related to this object.
This method ensures that the client connection is closed when exiting a context manager.
Args:
exc_type: The type of the exception that caused the context to be exited, if any.
exc_val: The instance of the exception that caused the context to be exited, if any.
exc_tb: A traceback object encoding the stack trace, if an exception occurred.
"""
self.close()
Loading

0 comments on commit 2649b27

Please sign in to comment.