Skip to content

Commit 1dea28f

Browse files
client: Enhance docstrings for consistency and clarity
- Revised docstrings across `PdfRestClient`, `AsyncPdfRestFilesClient`, and exception classes to follow Google-style formatting. - Improved descriptions and added missing sections like `Args`, `Returns`, and `Raises` for better usability and readability. - Updated models and types with refined docstrings to clearly explain usage, structure, and expected behaviors. Assisted-by: Codex
1 parent b4a91ee commit 1dea28f

6 files changed

Lines changed: 83 additions & 23 deletions

File tree

src/pdfrest/client.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1500,9 +1500,10 @@ async def __aexit__(self, exc_type: Any, exc: Any, traceback: Any) -> None:
15001500

15011501

15021502
class PdfRestFilesClient(Protocol):
1503-
"""Public interface for file operations returned by
1504-
[`PdfRestClient.files`][pdfrest.PdfRestClient.files].
1503+
"""Public interface for file operations returned by files helpers.
15051504
1505+
This protocol describes the object returned by
1506+
[`PdfRestClient.files`][pdfrest.PdfRestClient.files].
15061507
Retrieve this helper from `client.files`; do not instantiate it directly.
15071508
"""
15081509

@@ -1727,9 +1728,10 @@ def stream(
17271728

17281729

17291730
class AsyncPdfRestFilesClient(Protocol):
1730-
"""Public interface for file operations returned by
1731-
[`AsyncPdfRestClient.files`][pdfrest.AsyncPdfRestClient.files].
1731+
"""Public interface for async file operations returned by files helpers.
17321732
1733+
This protocol describes the object returned by
1734+
[`AsyncPdfRestClient.files`][pdfrest.AsyncPdfRestClient.files].
17331735
Retrieve this helper from `client.files`; do not instantiate it directly.
17341736
"""
17351737

src/pdfrest/exceptions.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,14 @@ def __init__(
6868
*,
6969
retry_after: float | None = None,
7070
) -> None:
71+
"""Initialize an API error with HTTP status and response details.
72+
73+
Args:
74+
status_code: HTTP status code returned by pdfRest.
75+
message: Optional human-readable error message.
76+
response_content: Parsed or raw error payload from the API response.
77+
retry_after: Optional retry delay in seconds parsed from headers.
78+
"""
7179
self.status_code = status_code
7280
self.response_content = response_content
7381
self.retry_after = retry_after
@@ -90,6 +98,12 @@ class PdfRestDeleteError(PdfRestError):
9098
"""Raised when an individual file cannot be deleted."""
9199

92100
def __init__(self, file_id: PdfRestFileID | str, message: str) -> None:
101+
"""Initialize a delete failure for one uploaded file.
102+
103+
Args:
104+
file_id: Identifier of the file that failed to delete.
105+
message: Error detail returned for the deletion attempt.
106+
"""
93107
self.file_id = str(file_id)
94108
self.detail = message
95109
super().__init__(f"Failed to delete file {self.file_id}: {message}")
@@ -99,6 +113,15 @@ class PdfRestErrorGroup(ExceptionGroup):
99113
"""Group of PdfRestError exceptions produced by the PDF REST library."""
100114

101115
def __init__(self, message: str, exceptions: Sequence[Exception], /) -> None:
116+
"""Initialize a grouped pdfRest failure.
117+
118+
Args:
119+
message: Summary message for the grouped error.
120+
exceptions: Collection of `PdfRestError` instances.
121+
122+
Raises:
123+
TypeError: If any item in `exceptions` is not a `PdfRestError`.
124+
"""
102125
# enforce that everything inside is from your library
103126
for e in exceptions:
104127
if not isinstance(e, PdfRestError):

src/pdfrest/models/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
"""Public model exports for the `pdfrest.models` package."""
2+
13
from .public import (
24
ExtractedTextDocument,
35
ExtractedTextFullText,

src/pdfrest/models/_internal.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2577,8 +2577,10 @@ class TiffPdfRestPayload(
25772577

25782578

25792579
class PdfRestRawUploadedFile(BaseModel):
2580-
"""The response sent by /upload is a list of these. /unzip returns files like this
2581-
with outputUrl
2580+
"""Raw uploaded-file entry returned by pdfRest upload-style endpoints.
2581+
2582+
The `/upload` response is a list of these objects. The `/unzip` response
2583+
also uses this shape and may include `outputUrl` entries.
25822584
"""
25832585

25842586
name: Annotated[str, Field(description="The name of the file")]

src/pdfrest/models/public.py

Lines changed: 47 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,9 @@
4646

4747

4848
class PdfRestFileID(str):
49-
"""A str-like type representing:
49+
"""Str-like identifier for pdfRest files.
50+
51+
Format:
5052
[optional '1' or '2' prefix] + [UUIDv4 with hyphens]
5153
5254
Examples:
@@ -71,6 +73,17 @@ class PdfRestFileID(str):
7173
)
7274

7375
def __new__(cls, value: str) -> PdfRestFileID:
76+
"""Create a normalized file identifier from a validated string.
77+
78+
Args:
79+
value: Candidate pdfRest file id string.
80+
81+
Returns:
82+
Lower-cased, validated file id value.
83+
84+
Raises:
85+
ValueError: If `value` is not a valid prefixed UUIDv4 identifier.
86+
"""
7487
if not cls._PY_PATTERN.fullmatch(value):
7588
msg = (
7689
"Invalid PdfRestPrefixedUUID4. Expected: "
@@ -116,8 +129,14 @@ def is_valid(cls, value: str) -> bool:
116129
def from_parts(
117130
cls, u: str | _uuid.UUID, prefix: int | str | None = None
118131
) -> PdfRestFileID:
119-
"""Build from a UUIDv4 (str or uuid.UUID) and an optional prefix (1 or 2).
120-
Raises ValueError if not a v4 UUID or bad prefix.
132+
"""Build a file id from a UUIDv4 and optional prefix.
133+
134+
Args:
135+
u: UUID value as string or `uuid.UUID`.
136+
prefix: Optional leading prefix (`1` or `2`).
137+
138+
Raises:
139+
ValueError: If the UUID is not version 4 or the prefix is invalid.
121140
"""
122141
if isinstance(prefix, int):
123142
prefix = str(prefix) # allow 1/2 as int
@@ -156,9 +175,11 @@ def generate(cls, prefix: int | str | None = None) -> PdfRestFileID:
156175
# -------------------------
157176
@classmethod
158177
def __get_pydantic_core_schema__(cls, source_type: Any, handler: Any) -> CoreSchema:
159-
"""Build a Pydantic v2 core schema that accepts:
160-
- a UUID (validated as v4) -> converted to this type (no prefix)
161-
- a string matching our pattern
178+
"""Build a Pydantic v2 core schema for `PdfRestFileID`.
179+
180+
Accepted inputs:
181+
- a UUID (validated as v4) converted to this type with no prefix
182+
- a string matching the `PdfRestFileID` pattern
162183
"""
163184
from pydantic_core import core_schema
164185

@@ -272,8 +293,10 @@ class PdfRestFile(BaseModel):
272293

273294

274295
class PdfRestFileBasedResponse(BaseModel):
275-
"""Represents a response from a pdfRest API operation that is file-based, allowing
276-
handling of input and output files along with additional warnings.
296+
"""Response model for file-based pdfRest operations.
297+
298+
Includes input file identifiers, output files, and optional warnings from
299+
the API response payload.
277300
"""
278301

279302
# Allow all extra fields to be stored and serialized
@@ -678,35 +701,43 @@ class ExtractedTextFullTextPages(BaseModel):
678701

679702

680703
class ExtractedTextFullText(RootModel[str | ExtractedTextFullTextPages]):
681-
"""Represents full-text extraction in either "document" (str) or "page" (object)
682-
modes while providing convenience accessors for both forms.
704+
"""Full-text extraction payload in document or per-page mode.
705+
706+
Wraps either a single document-level string or a per-page text object and
707+
provides convenience accessors for both shapes.
683708
"""
684709

685710
root: str | ExtractedTextFullTextPages
686711
"""Raw payload in document-text or per-page form."""
687712

688713
@property
689714
def document_text(self) -> str | None:
690-
"""Return the document-level string. Falls back to space-joining per-page text
691-
when only the page-structured payload is available.
715+
"""Return document-level text for either payload shape.
716+
717+
Falls back to joining per-page text when only the page-structured
718+
payload is available.
692719
"""
693720
if isinstance(self.root, str):
694721
return self.root
695722
return " ".join(page.text for page in self.root.pages)
696723

697724
@property
698725
def pages(self) -> list[ExtractedTextFullTextPage]:
699-
"""Return page entries when pdfRest emits per-page text.
700-
Raises ValueError when the payload is in document-string mode.
726+
"""Return per-page text entries when page mode is available.
727+
728+
Raises:
729+
ValueError: If the payload is in document-string mode.
701730
"""
702731
if isinstance(self.root, ExtractedTextFullTextPages):
703732
return self.root.pages
704733
msg = "full text payload was emitted in document mode; page data unavailable"
705734
raise ValueError(msg)
706735

707736
def iter_pages(self) -> list[ExtractedTextFullTextPage]:
708-
"""Convenience helper that provides a stable iterable without requiring
709-
callers to guard against the document-only representation.
737+
"""Return per-page text entries or an empty list in document mode.
738+
739+
This helper avoids forcing callers to catch mode errors when they only
740+
need an iterable.
710741
"""
711742
try:
712743
return self.pages

src/pdfrest/types/public.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ class PdfAddTextObject(TypedDict, total=False):
145145
font: Font family name used to render text.
146146
max_width: Maximum text box width in PDF points.
147147
opacity: Opacity value from 0.0 (transparent) to 1.0 (opaque).
148-
page: One-based page number or ``\"all\"`` for every page.
148+
page: One-based page number or ``"all"`` for every page.
149149
rotation: Rotation angle in degrees.
150150
text: Text content to draw.
151151
text_color_rgb: Optional RGB text color tuple.

0 commit comments

Comments
 (0)