Skip to content

Commit 12a0925

Browse files
committed
docs: Update docstrings
1 parent 9b8ce7c commit 12a0925

1 file changed

Lines changed: 80 additions & 40 deletions

File tree

mailjet_rest/client.py

Lines changed: 80 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
"""This module provides the main client and helper classes for interacting with the Mailjet API.
1+
"""Mailjet API v3, v3.1, and v1 Python wrapper.
22
3-
The `mailjet_rest.client` module includes the core `Client` class for managing
4-
API requests, configuration, and error handling, as well as utility functions
5-
and classes for building URLs and managing endpoints.
3+
This module provides the main client and helper classes for interacting
4+
with the Mailjet API. It handles authentication, secure URL construction,
5+
dynamic endpoint resolution, and request execution.
66
"""
77

88
from __future__ import annotations
@@ -60,13 +60,13 @@
6060

6161

6262
def prepare_url(match: Any) -> str:
63-
"""Replace capital letters in the input string with a dash prefix and converts them to lowercase.
63+
"""Replace capital letters in the input string with a dash prefix and convert to lowercase.
6464
6565
Args:
66-
match (Any): A regex match object.
66+
match (Any): A regex match object containing a capital letter.
6767
6868
Returns:
69-
str: A formatted URL string fragment.
69+
str: A formatted URL string fragment (e.g., '_m').
7070
"""
7171
return f"_{match.group(0).lower()}"
7272

@@ -151,7 +151,15 @@ def logging_handler(response: requests.Response) -> None: # noqa: ARG001
151151

152152
@dataclass
153153
class Config:
154-
"""Configuration settings for interacting with the Mailjet API."""
154+
"""Configuration settings for interacting with the Mailjet API.
155+
156+
Attributes:
157+
ALLOWED_ROOT_DOMAIN (ClassVar[str]): The permitted root domain to prevent SSRF.
158+
version (str): The API version to use (e.g., 'v3', 'v3.1', 'v1').
159+
api_url (str): The base URL for the Mailjet API.
160+
user_agent (str): The User-Agent string sent with API requests.
161+
timeout (int | float | tuple[float, float] | None): Request timeout in seconds.
162+
"""
155163

156164
ALLOWED_ROOT_DOMAIN: ClassVar[str] = "mailjet.com"
157165

@@ -161,7 +169,11 @@ class Config:
161169
timeout: int | float | tuple[float, float] | None = 60
162170

163171
def __post_init__(self) -> None:
164-
"""Validate configuration for secure transport and resource limits (OWASP Input Validation)."""
172+
"""Validate configuration for secure transport and resource limits (OWASP Input Validation).
173+
174+
Raises:
175+
ValueError: If the URL scheme is insecure or timeout bounds are violated.
176+
"""
165177
SecurityGuard.validate_config_url(self.api_url, allowed_root_domain=self.ALLOWED_ROOT_DOMAIN)
166178
if not self.api_url.endswith("/"):
167179
self.api_url += "/"
@@ -183,13 +195,13 @@ def _validate_timeout(t: float) -> None:
183195
_validate_timeout(cast("float", self.timeout))
184196

185197
def __getitem__(self, key: str) -> tuple[str, dict[str, str]]:
186-
"""Retrieve the API endpoint URL and headers for a given key.
198+
"""Retrieve the base API endpoint URL and default headers for a given key.
187199
188200
Args:
189-
key (str): The endpoint key name.
201+
key (str): The raw endpoint key name.
190202
191203
Returns:
192-
tuple[str, dict[str, str]]: The constructed URL and headers dictionary.
204+
tuple[str, dict[str, str]]: A tuple containing the base URL and the headers dictionary.
193205
"""
194206
action = key.split("_", maxsplit=1)[0]
195207
name_lower = key.lower()
@@ -212,14 +224,18 @@ def __getitem__(self, key: str) -> tuple[str, dict[str, str]]:
212224

213225

214226
class Endpoint:
215-
"""A class representing a specific Mailjet API endpoint."""
227+
"""A class representing a specific Mailjet API endpoint.
228+
229+
This class provides methods to execute standard HTTP operations (GET, POST, PUT, DELETE)
230+
dynamically based on the requested resource.
231+
"""
216232

217233
def __init__(self, client: Client, name: str) -> None:
218234
"""Initialize a new Endpoint instance.
219235
220236
Args:
221-
client (Client): The core client instance.
222-
name (str): The endpoint resource name.
237+
client (Client): The active API client managing the session.
238+
name (str): The resource name (e.g., 'contact', 'send', 'contactslist_csvdata').
223239
"""
224240
self.client = client
225241
self.name = name
@@ -327,19 +343,19 @@ def __call__(
327343
"""Execute the API call directly.
328344
329345
Args:
330-
method (Literal["GET", "POST", "PUT", "DELETE"]): The HTTP method.
331-
filters (dict[str, Any] | None): Query parameters.
332-
data (dict[str, Any] | list[Any] | str | None): Request payload.
333-
headers (dict[str, str] | None): Custom headers.
334-
id (int | str | None): Primary resource ID.
335-
action_id (int | str | None): Sub-action ID.
336-
timeout (int | float | tuple[float, float] | None): Request timeout.
337-
ensure_ascii (bool | None): Ensure ASCII serialization (Deprecated).
338-
data_encoding (str | None): Data encoding string (Deprecated).
339-
**kwargs (Any): Additional arguments.
346+
method (Literal["GET", "POST", "PUT", "DELETE"], optional): The HTTP method. Defaults to "GET".
347+
filters (dict[str, Any] | None, optional): Query parameters to append to the URL.
348+
data (dict[str, Any] | list[Any] | str | None, optional): The payload for the request body.
349+
headers (dict[str, str] | None, optional): Additional HTTP headers to send.
350+
id (int | str | None, optional): The primary resource ID.
351+
action_id (int | str | None, optional): The secondary ID or action string for nested resources.
352+
timeout (int | float | tuple[float, float] | None, optional): Custom timeout for this request.
353+
ensure_ascii (bool | None, optional): Deprecated. Ensure ASCII serialization.
354+
data_encoding (str | None, optional): Deprecated. Target encoding string for the payload.
355+
**kwargs (Any): Additional parameters passed to `requests.Session.request`.
340356
341357
Returns:
342-
requests.Response: The HTTP response from the API.
358+
requests.Response: The HTTP response from the Mailjet API.
343359
"""
344360
if id is None and action_id is not None:
345361
id = action_id # noqa: A001
@@ -473,15 +489,36 @@ def delete(self, id: int | str, action_id: int | str | None = None, **kwargs: An
473489

474490

475491
class Client:
476-
"""A client for interacting with the Mailjet API."""
492+
"""The primary client for interacting with the Mailjet API.
493+
494+
Handles authentication, session management, configuration, and dynamic
495+
endpoint resolution via magic methods (`__getattr__`).
496+
497+
Examples:
498+
>>> client = Client(auth=(API_KEY, API_SECRET), version='v3.1')
499+
>>> response = client.send.create(data=payload)
500+
"""
477501

478502
def __init__(
479503
self,
480504
auth: tuple[str, str] | str | None = None,
481505
config: Config | None = None,
482506
**kwargs: Any,
483507
) -> None:
484-
"""Initialize a new Client instance."""
508+
"""Initialize a new Mailjet API Client instance.
509+
510+
Args:
511+
auth (tuple[str, str] | str | None, optional): Authentication credentials.
512+
Use a tuple `(API_KEY, API_SECRET)` for Basic Auth (Email API).
513+
Use a string `TOKEN` for Bearer Auth (Content API v1).
514+
config (Config | None, optional): A pre-configured `Config` instance.
515+
**kwargs (Any): Configuration overrides if `config` is not provided
516+
(e.g., `version='v3.1'`, `timeout=10`).
517+
518+
Raises:
519+
ValueError: If the provided `auth` credentials are invalid or empty.
520+
TypeError: If the `auth` type is neither a tuple nor a string.
521+
"""
485522
self.config = config or Config(**kwargs)
486523
self.session = requests.Session()
487524

@@ -680,26 +717,29 @@ def api_call(
680717
data_encoding: str | None = None,
681718
**kwargs: Any,
682719
) -> requests.Response:
683-
"""Perform the actual network request using the persistent session.
720+
"""Perform the actual network request using the persistent HTTP session.
721+
722+
This method acts as the core orchestrator, handling telemetry extraction,
723+
payload serialization, security guardrails, and centralized logging.
684724
685725
Args:
686726
method (Literal["GET", "POST", "PUT", "DELETE"]): The HTTP method.
687-
url (str): The fully constructed URL.
688-
filters (dict[str, Any] | None): Query parameters.
689-
data (dict[str, Any] | list[Any] | str | None): Request payload.
690-
headers (dict[str, str] | None): HTTP headers.
691-
timeout (int | float | tuple[float, float] | None): Request timeout.
692-
ensure_ascii (bool | None): Ensure ASCII encoding (deprecated).
693-
data_encoding (str | None): Data encoding (deprecated).
694-
**kwargs (Any): Additional arguments.
727+
url (str): The fully constructed API URL.
728+
filters (dict[str, Any] | None, optional): Query parameters.
729+
data (dict[str, Any] | list[Any] | str | None, optional): Request payload.
730+
headers (dict[str, str] | None, optional): Custom HTTP headers.
731+
timeout (int | float | tuple[float, float] | None, optional): Request timeout.
732+
ensure_ascii (bool | None, optional): Deprecated. Ensure ASCII encoding.
733+
data_encoding (str | None, optional): Deprecated. Data encoding string.
734+
**kwargs (Any): Additional arguments passed to `requests.Session.request`.
695735
696736
Returns:
697-
requests.Response: The HTTP response from the API.
737+
requests.Response: The HTTP response from the Mailjet API.
698738
699739
Raises:
700740
TimeoutError: If the API request times out.
701-
CriticalApiError: If there is a connection failure.
702-
ApiError: For other unhandled request exceptions.
741+
CriticalApiError: If a connection failure occurs.
742+
ApiError: For other unhandled network exceptions.
703743
"""
704744
request_data = self._prepare_payload(data, ensure_ascii, data_encoding)
705745
timeout_val = timeout if timeout is not None else self.config.timeout

0 commit comments

Comments
 (0)