Skip to content

Commit e0fc644

Browse files
client: Add PdfRestFilesClient and AsyncPdfRestFilesClient interfaces
- Introduced `PdfRestFilesClient` and `AsyncPdfRestFilesClient` protocol interfaces for managing file operations, including methods to handle file uploads, retrievals, deletions, and content operations. - Updated the `PdfRestClient` and `AsyncPdfRestClient` classes to expose the file clients via the `files` property. - Updated `__all__` definitions in `__init__.py` and `client.py` to include the newly added clients. - Refactored `_FilesClient` and `_AsyncFilesClient` to adhere to the new interface protocols, improving type safety and clarity. Assisted-by: Codex
1 parent 0ab9fdd commit e0fc644

2 files changed

Lines changed: 237 additions & 6 deletions

File tree

src/pdfrest/__init__.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@
22

33
from importlib import metadata
44

5-
from .client import AsyncPdfRestClient, PdfRestClient
5+
from .client import (
6+
AsyncPdfRestClient,
7+
AsyncPdfRestFilesClient,
8+
PdfRestClient,
9+
PdfRestFilesClient,
10+
)
611
from .exceptions import (
712
PdfRestApiError,
813
PdfRestAuthenticationError,
@@ -19,13 +24,15 @@
1924

2025
__all__ = (
2126
"AsyncPdfRestClient",
27+
"AsyncPdfRestFilesClient",
2228
"PdfRestApiError",
2329
"PdfRestAuthenticationError",
2430
"PdfRestClient",
2531
"PdfRestConfigurationError",
2632
"PdfRestDeleteError",
2733
"PdfRestError",
2834
"PdfRestErrorGroup",
35+
"PdfRestFilesClient",
2936
"PdfRestRequestError",
3037
"PdfRestTimeoutError",
3138
"PdfRestTransportError",

src/pdfrest/client.py

Lines changed: 229 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
Any,
2929
Generic,
3030
Literal,
31+
Protocol,
3132
TypeAlias,
3233
TypeVar,
3334
cast,
@@ -139,7 +140,12 @@
139140
TranslateOutputFormat,
140141
)
141142

142-
__all__ = ("AsyncPdfRestClient", "PdfRestClient")
143+
__all__ = (
144+
"AsyncPdfRestClient",
145+
"AsyncPdfRestFilesClient",
146+
"PdfRestClient",
147+
"PdfRestFilesClient",
148+
)
143149
FileResponseModel = TypeVar("FileResponseModel", bound=PdfRestFileBasedResponse)
144150

145151
DEFAULT_BASE_URL = "https://api.pdfrest.com"
@@ -1463,6 +1469,210 @@ async def __aexit__(self, exc_type: Any, exc: Any, traceback: Any) -> None:
14631469
await self.close()
14641470

14651471

1472+
class PdfRestFilesClient(Protocol):
1473+
"""Public interface for file operations returned by
1474+
[`PdfRestClient.files`][pdfrest.PdfRestClient.files].
1475+
1476+
Retrieve this helper from `client.files`; do not instantiate it directly.
1477+
"""
1478+
1479+
def get(
1480+
self,
1481+
id: PdfRestFileID | str,
1482+
*,
1483+
extra_query: Query | None = None,
1484+
extra_headers: AnyMapping | None = None,
1485+
timeout: TimeoutTypes | None = None,
1486+
) -> PdfRestFile: ...
1487+
1488+
def create(
1489+
self,
1490+
files: UploadFiles,
1491+
*,
1492+
extra_query: Query | None = None,
1493+
extra_headers: AnyMapping | None = None,
1494+
timeout: TimeoutTypes | None = None,
1495+
) -> list[PdfRestFile]: ...
1496+
1497+
def create_from_paths(
1498+
self,
1499+
file_paths: FilePathInput,
1500+
*,
1501+
extra_query: Query | None = None,
1502+
extra_headers: AnyMapping | None = None,
1503+
timeout: TimeoutTypes | None = None,
1504+
) -> list[PdfRestFile]: ...
1505+
1506+
def create_from_urls(
1507+
self,
1508+
urls: UrlInput,
1509+
*,
1510+
extra_query: Query | None = None,
1511+
extra_headers: AnyMapping | None = None,
1512+
extra_body: Body | None = None,
1513+
timeout: TimeoutTypes | None = None,
1514+
) -> list[PdfRestFile]: ...
1515+
1516+
def delete(
1517+
self,
1518+
files: PdfRestFile | Sequence[PdfRestFile],
1519+
*,
1520+
extra_query: Query | None = None,
1521+
extra_headers: AnyMapping | None = None,
1522+
extra_body: Body | None = None,
1523+
timeout: TimeoutTypes | None = None,
1524+
) -> None: ...
1525+
1526+
def read_bytes(
1527+
self,
1528+
file_ref: PdfRestFile | str,
1529+
*,
1530+
extra_query: Query | None = None,
1531+
extra_headers: AnyMapping | None = None,
1532+
timeout: TimeoutTypes | None = None,
1533+
) -> bytes: ...
1534+
1535+
def read_text(
1536+
self,
1537+
file_ref: PdfRestFile | str,
1538+
*,
1539+
encoding: str = "utf-8",
1540+
extra_query: Query | None = None,
1541+
extra_headers: AnyMapping | None = None,
1542+
timeout: TimeoutTypes | None = None,
1543+
) -> str: ...
1544+
1545+
def read_json(
1546+
self,
1547+
file_ref: PdfRestFile | str,
1548+
*,
1549+
extra_query: Query | None = None,
1550+
extra_headers: AnyMapping | None = None,
1551+
timeout: TimeoutTypes | None = None,
1552+
) -> Any: ...
1553+
1554+
def write_bytes(
1555+
self,
1556+
file_ref: PdfRestFile | str,
1557+
destination: DestinationPath,
1558+
*,
1559+
extra_query: Query | None = None,
1560+
extra_headers: AnyMapping | None = None,
1561+
timeout: TimeoutTypes | None = None,
1562+
) -> Path: ...
1563+
1564+
def stream(
1565+
self,
1566+
file_ref: PdfRestFile | str,
1567+
*,
1568+
extra_query: Query | None = None,
1569+
extra_headers: AnyMapping | None = None,
1570+
timeout: TimeoutTypes | None = None,
1571+
) -> PdfRestFileStream: ...
1572+
1573+
1574+
class AsyncPdfRestFilesClient(Protocol):
1575+
"""Public interface for file operations returned by
1576+
[`AsyncPdfRestClient.files`][pdfrest.AsyncPdfRestClient.files].
1577+
1578+
Retrieve this helper from `client.files`; do not instantiate it directly.
1579+
"""
1580+
1581+
async def get(
1582+
self,
1583+
id: PdfRestFileID | str,
1584+
*,
1585+
extra_query: Query | None = None,
1586+
extra_headers: AnyMapping | None = None,
1587+
timeout: TimeoutTypes | None = None,
1588+
) -> PdfRestFile: ...
1589+
1590+
async def create(
1591+
self,
1592+
files: UploadFiles,
1593+
*,
1594+
extra_query: Query | None = None,
1595+
extra_headers: AnyMapping | None = None,
1596+
timeout: TimeoutTypes | None = None,
1597+
) -> list[PdfRestFile]: ...
1598+
1599+
async def create_from_paths(
1600+
self,
1601+
file_paths: FilePathInput,
1602+
*,
1603+
extra_query: Query | None = None,
1604+
extra_headers: AnyMapping | None = None,
1605+
timeout: TimeoutTypes | None = None,
1606+
) -> list[PdfRestFile]: ...
1607+
1608+
async def create_from_urls(
1609+
self,
1610+
urls: UrlInput,
1611+
*,
1612+
extra_query: Query | None = None,
1613+
extra_headers: AnyMapping | None = None,
1614+
extra_body: Body | None = None,
1615+
timeout: TimeoutTypes | None = None,
1616+
) -> list[PdfRestFile]: ...
1617+
1618+
async def delete(
1619+
self,
1620+
files: PdfRestFile | Sequence[PdfRestFile],
1621+
*,
1622+
extra_query: Query | None = None,
1623+
extra_headers: AnyMapping | None = None,
1624+
extra_body: Body | None = None,
1625+
timeout: TimeoutTypes | None = None,
1626+
) -> None: ...
1627+
1628+
async def read_bytes(
1629+
self,
1630+
file_ref: PdfRestFile | str,
1631+
*,
1632+
extra_query: Query | None = None,
1633+
extra_headers: AnyMapping | None = None,
1634+
timeout: TimeoutTypes | None = None,
1635+
) -> bytes: ...
1636+
1637+
async def read_text(
1638+
self,
1639+
file_ref: PdfRestFile | str,
1640+
*,
1641+
encoding: str = "utf-8",
1642+
extra_query: Query | None = None,
1643+
extra_headers: AnyMapping | None = None,
1644+
timeout: TimeoutTypes | None = None,
1645+
) -> str: ...
1646+
1647+
async def read_json(
1648+
self,
1649+
file_ref: PdfRestFile | str,
1650+
*,
1651+
extra_query: Query | None = None,
1652+
extra_headers: AnyMapping | None = None,
1653+
timeout: TimeoutTypes | None = None,
1654+
) -> Any: ...
1655+
1656+
async def write_bytes(
1657+
self,
1658+
file_ref: PdfRestFile | str,
1659+
destination: DestinationPath,
1660+
*,
1661+
extra_query: Query | None = None,
1662+
extra_headers: AnyMapping | None = None,
1663+
timeout: TimeoutTypes | None = None,
1664+
) -> Path: ...
1665+
1666+
async def stream(
1667+
self,
1668+
file_ref: PdfRestFile | str,
1669+
*,
1670+
extra_query: Query | None = None,
1671+
extra_headers: AnyMapping | None = None,
1672+
timeout: TimeoutTypes | None = None,
1673+
) -> AsyncPdfRestFileStream: ...
1674+
1675+
14661676
class _FilesClient:
14671677
"""Expose file-related operations for the synchronous client."""
14681678

@@ -2068,7 +2278,8 @@ def __init__(
20682278
transport=transport,
20692279
max_retries=max_retries,
20702280
)
2071-
self._files_client = _FilesClient(self)
2281+
files_client: PdfRestFilesClient = _FilesClient(self)
2282+
self._files_client = files_client
20722283

20732284
@override
20742285
def __enter__(self) -> PdfRestClient:
@@ -2080,7 +2291,13 @@ def __exit__(self, exc_type: Any, exc: Any, traceback: Any) -> None:
20802291
super().__exit__(exc_type, exc, traceback)
20812292

20822293
@property
2083-
def files(self) -> _FilesClient:
2294+
def files(self) -> PdfRestFilesClient:
2295+
"""File-management helper implementing
2296+
[`PdfRestFilesClient`][pdfrest.PdfRestFilesClient].
2297+
2298+
Retrieve this helper from `client.files`; do not instantiate it directly.
2299+
"""
2300+
20842301
return self._files_client
20852302

20862303
def up(
@@ -3448,7 +3665,8 @@ def __init__(
34483665
concurrency_limit=concurrency_limit,
34493666
max_retries=max_retries,
34503667
)
3451-
self._files_client = _AsyncFilesClient(self)
3668+
files_client: AsyncPdfRestFilesClient = _AsyncFilesClient(self)
3669+
self._files_client = files_client
34523670

34533671
@override
34543672
async def __aenter__(self) -> AsyncPdfRestClient:
@@ -3460,7 +3678,13 @@ async def __aexit__(self, exc_type: Any, exc: Any, traceback: Any) -> None:
34603678
await super().__aexit__(exc_type, exc, traceback)
34613679

34623680
@property
3463-
def files(self) -> _AsyncFilesClient:
3681+
def files(self) -> AsyncPdfRestFilesClient:
3682+
"""Async file-management helper implementing
3683+
[`AsyncPdfRestFilesClient`][pdfrest.AsyncPdfRestFilesClient].
3684+
3685+
Retrieve this helper from `client.files`; do not instantiate it directly.
3686+
"""
3687+
34643688
return self._files_client
34653689

34663690
async def query_pdf_info(

0 commit comments

Comments
 (0)