@@ -52,6 +52,33 @@ def test_extract_pdf_text_payload_invalid_page_range() -> None:
5252 ExtractTextPayload .model_validate ({"files" : [file_repr ], "pages" : ["5-2" ]})
5353
5454
55+ @pytest .mark .asyncio
56+ async def test_async_extract_pdf_text_payload_rejects_non_pdf () -> None :
57+ file_id = str (PdfRestFileID .generate ())
58+ text_file = PdfRestFile .model_validate (
59+ {
60+ "id" : file_id ,
61+ "name" : "notes.txt" ,
62+ "url" : f"https://api.pdfrest.com/resource/{ file_id } " ,
63+ "type" : "text/plain" ,
64+ "size" : 64 ,
65+ "modified" : "2024-01-01T00:00:00Z" ,
66+ "scheduledDeletionTimeUtc" : None ,
67+ }
68+ )
69+ with pytest .raises (ValidationError , match = "Must be a PDF file" ):
70+ ExtractTextPayload .model_validate ({"files" : [text_file ]})
71+
72+
73+ @pytest .mark .asyncio
74+ async def test_async_extract_pdf_text_payload_invalid_page_range () -> None :
75+ file_repr = make_pdf_file (PdfRestFileID .generate (1 ))
76+ with pytest .raises (
77+ ValidationError , match = "The start page must be less than or equal to the end"
78+ ):
79+ ExtractTextPayload .model_validate ({"files" : [file_repr ], "pages" : ["5-2" ]})
80+
81+
5582def test_extract_pdf_text_to_file_success (monkeypatch : pytest .MonkeyPatch ) -> None :
5683 monkeypatch .delenv ("PDFREST_API_KEY" , raising = False )
5784 input_file = make_pdf_file (PdfRestFileID .generate (1 ))
@@ -186,6 +213,85 @@ def handler(request: httpx.Request) -> httpx.Response:
186213 assert get_timeout == pytest .approx (0.35 )
187214
188215
216+ @pytest .mark .asyncio
217+ async def test_async_extract_pdf_text_request_customization (
218+ monkeypatch : pytest .MonkeyPatch ,
219+ ) -> None :
220+ monkeypatch .delenv ("PDFREST_API_KEY" , raising = False )
221+ input_file = make_pdf_file (PdfRestFileID .generate (2 ))
222+ output_id = str (PdfRestFileID .generate ())
223+ payload_dump = ExtractTextPayload .model_validate (
224+ {
225+ "files" : [input_file ],
226+ "output" : "file-output" ,
227+ "full_text" : "document" ,
228+ "preserve_line_breaks" : "off" ,
229+ "word_style" : "off" ,
230+ "word_coordinates" : "off" ,
231+ "output_type" : "file" ,
232+ }
233+ ).model_dump (mode = "json" , by_alias = True , exclude_none = True , exclude_unset = True )
234+ captured_timeout : dict [str , float | dict [str , float ] | None ] = {}
235+
236+ def handler (request : httpx .Request ) -> httpx .Response :
237+ if request .method == "POST" and request .url .path == "/extracted-text" :
238+ assert request .url .params ["trace" ] == "true"
239+ assert request .headers ["X-Debug" ] == "async"
240+ captured_timeout ["post" ] = request .extensions .get ("timeout" )
241+ payload = json .loads (request .content .decode ("utf-8" ))
242+ assert payload == payload_dump | {"debug" : True }
243+ return httpx .Response (
244+ 200 ,
245+ json = {
246+ "inputId" : [str (input_file .id )],
247+ "outputId" : [output_id ],
248+ },
249+ )
250+ if request .method == "GET" and request .url .path == f"/resource/{ output_id } " :
251+ assert request .url .params ["format" ] == "info"
252+ assert request .url .params ["trace" ] == "true"
253+ assert request .headers ["X-Debug" ] == "async"
254+ captured_timeout ["get" ] = request .extensions .get ("timeout" )
255+ return httpx .Response (
256+ 200 ,
257+ json = _make_text_file (output_id , "debug-async.txt" ).model_dump (
258+ mode = "json" , by_alias = True
259+ ),
260+ )
261+ msg = f"Unexpected request { request .method } { request .url } "
262+ raise AssertionError (msg )
263+
264+ transport = httpx .MockTransport (handler )
265+ async with AsyncPdfRestClient (api_key = ASYNC_API_KEY , transport = transport ) as client :
266+ response = await client .extract_pdf_text_to_file (
267+ input_file ,
268+ output = "file-output" ,
269+ extra_query = {"trace" : "true" },
270+ extra_headers = {"X-Debug" : "async" },
271+ extra_body = {"debug" : True },
272+ timeout = 0.35 ,
273+ )
274+
275+ assert isinstance (response , PdfRestFileBasedResponse )
276+ assert len (response .output_files ) == 1
277+ post_timeout = captured_timeout ["post" ]
278+ get_timeout = captured_timeout ["get" ]
279+ assert post_timeout is not None
280+ assert get_timeout is not None
281+ if isinstance (post_timeout , dict ):
282+ assert all (
283+ component == pytest .approx (0.35 ) for component in post_timeout .values ()
284+ )
285+ else :
286+ assert post_timeout == pytest .approx (0.35 )
287+ if isinstance (get_timeout , dict ):
288+ assert all (
289+ component == pytest .approx (0.35 ) for component in get_timeout .values ()
290+ )
291+ else :
292+ assert get_timeout == pytest .approx (0.35 )
293+
294+
189295@pytest .mark .asyncio
190296async def test_async_extract_pdf_text_to_file_success (
191297 monkeypatch : pytest .MonkeyPatch ,
0 commit comments