@@ -896,6 +896,22 @@ def _send_request(self, request: _RequestModel) -> Any:
896896 should_continue = stream_retry_checker ,
897897 )
898898
899+ def send_request_once (self , request : _RequestModel ) -> Any :
900+ return self ._perform_request (self ._client , request )
901+
902+ def run_with_retry (
903+ self ,
904+ func : Callable [[], ReturnType ],
905+ * ,
906+ operation : str ,
907+ should_continue : Callable [[PdfRestError ], bool ] | None = None ,
908+ ) -> ReturnType :
909+ return self ._execute_with_retry (
910+ func ,
911+ operation = operation ,
912+ should_continue = should_continue ,
913+ )
914+
899915 def _perform_request (
900916 self , http_client : httpx .Client , request : _RequestModel
901917 ) -> Any :
@@ -1143,6 +1159,22 @@ async def _send_request(self, request: _RequestModel) -> Any:
11431159 should_continue = stream_retry_checker ,
11441160 )
11451161
1162+ async def send_request_once (self , request : _RequestModel ) -> Any :
1163+ return await self ._perform_request (self ._client , request )
1164+
1165+ async def run_with_retry (
1166+ self ,
1167+ func : Callable [[], Awaitable [ReturnType ]],
1168+ * ,
1169+ operation : str ,
1170+ should_continue : Callable [[PdfRestError ], bool ] | None = None ,
1171+ ) -> ReturnType :
1172+ return await self ._execute_with_retry (
1173+ func ,
1174+ operation = operation ,
1175+ should_continue = should_continue ,
1176+ )
1177+
11461178 async def _perform_request (
11471179 self , http_client : httpx .AsyncClient , request : _RequestModel
11481180 ) -> Any :
@@ -1441,25 +1473,42 @@ def create_from_paths(
14411473 closed once the request completes.
14421474 """
14431475 normalized_paths = _normalize_path_inputs (file_paths )
1444-
1445- with ExitStack () as stack :
1446- upload_specs : list [FileTypes ] = []
1447- for spec in normalized_paths :
1448- path , content_type , headers = _parse_path_spec (spec )
1449- file_obj = stack .enter_context (path .open ("rb" ))
1450- filename = path .name
1451- if headers :
1452- upload_specs .append ((filename , file_obj , content_type , headers ))
1453- elif content_type is not None :
1454- upload_specs .append ((filename , file_obj , content_type ))
1455- else :
1456- upload_specs .append ((filename , file_obj ))
1457- return self .create (
1458- upload_specs ,
1459- extra_query = extra_query ,
1460- extra_headers = extra_headers ,
1461- timeout = timeout ,
1462- )
1476+ path_specs = [_parse_path_spec (spec ) for spec in normalized_paths ]
1477+
1478+ def attempt () -> list [PdfRestFile ]:
1479+ with ExitStack () as stack :
1480+ upload_specs : list [FileTypes ] = []
1481+ for path , content_type , headers in path_specs :
1482+ file_obj = stack .enter_context (path .open ("rb" ))
1483+ filename = path .name
1484+ if headers :
1485+ upload_specs .append ((filename , file_obj , content_type , headers ))
1486+ elif content_type is not None :
1487+ upload_specs .append ((filename , file_obj , content_type ))
1488+ else :
1489+ upload_specs .append ((filename , file_obj ))
1490+
1491+ request = self ._client .prepare_request (
1492+ "POST" ,
1493+ "/upload" ,
1494+ files = upload_specs ,
1495+ extra_query = extra_query ,
1496+ extra_headers = extra_headers ,
1497+ timeout = timeout ,
1498+ )
1499+ payload = self ._client .send_request_once (request )
1500+ file_ids = _extract_uploaded_file_ids (payload )
1501+ return [
1502+ self ._client .fetch_file_info (
1503+ file_id ,
1504+ extra_query = extra_query ,
1505+ extra_headers = extra_headers ,
1506+ timeout = timeout ,
1507+ )
1508+ for file_id in file_ids
1509+ ]
1510+
1511+ return self ._client .run_with_retry (attempt , operation = "POST /upload (paths)" )
14631512
14641513 def create_from_urls (
14651514 self ,
@@ -1681,25 +1730,54 @@ async def create_from_paths(
16811730 closed once the request completes.
16821731 """
16831732 normalized_paths = _normalize_path_inputs (file_paths )
1684-
1685- with ExitStack () as stack :
1686- upload_specs : list [FileTypes ] = []
1687- for spec in normalized_paths :
1688- path , content_type , headers = _parse_path_spec (spec )
1689- file_obj = stack .enter_context (path .open ("rb" ))
1690- filename = path .name
1691- if headers :
1692- upload_specs .append ((filename , file_obj , content_type , headers ))
1693- elif content_type is not None :
1694- upload_specs .append ((filename , file_obj , content_type ))
1695- else :
1696- upload_specs .append ((filename , file_obj ))
1697- return await self .create (
1698- upload_specs ,
1699- extra_query = extra_query ,
1700- extra_headers = extra_headers ,
1701- timeout = timeout ,
1702- )
1733+ path_specs = [_parse_path_spec (spec ) for spec in normalized_paths ]
1734+
1735+ async def attempt () -> list [PdfRestFile ]:
1736+ with ExitStack () as stack :
1737+ upload_specs : list [FileTypes ] = []
1738+ for path , content_type , headers in path_specs :
1739+ file_obj = stack .enter_context (path .open ("rb" ))
1740+ filename = path .name
1741+ if headers :
1742+ upload_specs .append ((filename , file_obj , content_type , headers ))
1743+ elif content_type is not None :
1744+ upload_specs .append ((filename , file_obj , content_type ))
1745+ else :
1746+ upload_specs .append ((filename , file_obj ))
1747+
1748+ request = self ._client .prepare_request (
1749+ "POST" ,
1750+ "/upload" ,
1751+ files = upload_specs ,
1752+ extra_query = extra_query ,
1753+ extra_headers = extra_headers ,
1754+ timeout = timeout ,
1755+ )
1756+ payload = await self ._client .send_request_once (request )
1757+ file_ids = _extract_uploaded_file_ids (payload )
1758+ results : list [PdfRestFile ] = []
1759+ semaphore = asyncio .Semaphore (self ._concurrency_limit )
1760+
1761+ async def throttled_fetch (file_id : str ) -> PdfRestFile :
1762+ async with semaphore :
1763+ return await self ._client .fetch_file_info (
1764+ file_id ,
1765+ extra_query = extra_query ,
1766+ extra_headers = extra_headers ,
1767+ timeout = timeout ,
1768+ )
1769+
1770+ if file_ids :
1771+ results = list (
1772+ await asyncio .gather (
1773+ * (throttled_fetch (fid ) for fid in file_ids )
1774+ )
1775+ )
1776+ return results
1777+
1778+ return await self ._client .run_with_retry (
1779+ attempt , operation = "POST /upload (paths)"
1780+ )
17031781
17041782 async def create_from_urls (
17051783 self ,
0 commit comments