44for supported document processing operations.
55"""
66
7- from typing import TYPE_CHECKING , Any , List , Optional
7+ from typing import TYPE_CHECKING , Any , List , Optional , Protocol , cast
88
99from nutrient_dws .file_handler import FileInput
1010
1111if TYPE_CHECKING :
12- from nutrient_dws .client import NutrientClient
12+ from nutrient_dws .builder import BuildAPIWrapper
13+ from nutrient_dws .http_client import HTTPClient
14+
15+
16+ class HasBuildMethod (Protocol ):
17+ """Protocol for objects that have a build method."""
18+
19+ def build (self , input_file : FileInput ) -> "BuildAPIWrapper" :
20+ """Build method signature."""
21+ ...
22+
23+ @property
24+ def _http_client (self ) -> "HTTPClient" :
25+ """HTTP client property."""
26+ ...
1327
1428
1529class DirectAPIMixin :
1630 """Mixin class containing Direct API methods.
17-
31+
1832 These methods provide a simplified interface to common document
1933 processing operations. They internally use the Build API.
20-
34+
2135 Note: The API automatically converts supported document formats
2236 (DOCX, XLSX, PPTX) to PDF when processing.
2337 """
2438
2539 def _process_file (
26- self : "NutrientClient" ,
40+ self ,
2741 tool : str ,
2842 input_file : FileInput ,
2943 output_path : Optional [str ] = None ,
@@ -40,7 +54,7 @@ def convert_to_pdf(
4054 """Convert a document to PDF.
4155
4256 Converts Office documents (DOCX, XLSX, PPTX) to PDF format.
43- This uses the API's implicit conversion - simply uploading a
57+ This uses the API's implicit conversion - simply uploading a
4458 non-PDF document returns it as a PDF.
4559
4660 Args:
@@ -53,12 +67,14 @@ def convert_to_pdf(
5367 Raises:
5468 AuthenticationError: If API key is missing or invalid.
5569 APIError: For other API errors (e.g., unsupported format).
56-
70+
5771 Note:
5872 HTML files are not currently supported by the API.
5973 """
6074 # Use builder with no actions - implicit conversion happens
61- return self .build (input_file ).execute (output_path ) # type: ignore
75+ if TYPE_CHECKING :
76+ self = cast (HasBuildMethod , self )
77+ return self .build (input_file ).execute (output_path )
6278
6379 def flatten_annotations (
6480 self , input_file : FileInput , output_path : Optional [str ] = None
@@ -120,7 +136,7 @@ def ocr_pdf(
120136 """Apply OCR to a PDF to make it searchable.
121137
122138 Performs optical character recognition on the PDF to extract text
123- and make it searchable. If input is an Office document, it will
139+ and make it searchable. If input is an Office document, it will
124140 be converted to PDF first.
125141
126142 Args:
@@ -199,7 +215,7 @@ def apply_redactions(
199215 """Apply redaction annotations to permanently remove content.
200216
201217 Applies any redaction annotations in the PDF to permanently remove
202- the underlying content. If input is an Office document, it will
218+ the underlying content. If input is an Office document, it will
203219 be converted to PDF first.
204220
205221 Args:
@@ -216,14 +232,14 @@ def apply_redactions(
216232 return self ._process_file ("apply-redactions" , input_file , output_path )
217233
218234 def merge_pdfs (
219- self : "NutrientClient" ,
235+ self ,
220236 input_files : List [FileInput ],
221237 output_path : Optional [str ] = None ,
222238 ) -> Optional [bytes ]:
223239 """Merge multiple PDF files into one.
224240
225241 Combines multiple files into a single PDF in the order provided.
226- Office documents (DOCX, XLSX, PPTX) will be automatically converted
242+ Office documents (DOCX, XLSX, PPTX) will be automatically converted
227243 to PDF before merging.
228244
229245 Args:
@@ -237,7 +253,7 @@ def merge_pdfs(
237253 AuthenticationError: If API key is missing or invalid.
238254 APIError: For other API errors.
239255 ValueError: If less than 2 files provided.
240-
256+
241257 Example:
242258 # Merge PDFs and Office documents
243259 client.merge_pdfs([
@@ -262,12 +278,11 @@ def merge_pdfs(
262278 parts .append ({"file" : field_name })
263279
264280 # Build instructions for merge (no actions needed)
265- instructions = {
266- "parts" : parts ,
267- "actions" : []
268- }
281+ instructions = {"parts" : parts , "actions" : []}
269282
270283 # Make API request
284+ if TYPE_CHECKING :
285+ self = cast (HasBuildMethod , self )
271286 result = self ._http_client .post (
272287 "/build" ,
273288 files = files ,
0 commit comments