Skip to content

Commit bedc38e

Browse files
committed
feat: add implicit document conversion support
- Discovered that the Nutrient API automatically converts Office documents (DOCX, XLSX, PPTX) to PDF - Added convert_to_pdf method that leverages implicit conversion - Updated all Direct API method documentation to reflect Office document support - Updated SUPPORTED_OPERATIONS.md with comprehensive documentation of the discovery - All methods now accept both PDFs and Office documents seamlessly - Updated examples to show mixing PDFs and Office documents in operations like merge This is a significant improvement to the library's capabilities, as users can now: - Convert Office documents to PDF without explicit conversion steps - Use any processing operation (rotate, OCR, watermark, etc.) directly on Office files - Mix PDFs and Office documents in merge operations
1 parent caaacae commit bedc38e

File tree

2 files changed

+129
-29
lines changed

2 files changed

+129
-29
lines changed

SUPPORTED_OPERATIONS.md

Lines changed: 75 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,64 @@
22

33
This document lists all operations currently supported by the Nutrient DWS API through this Python client.
44

5+
## 🎯 Important Discovery: Implicit Document Conversion
6+
7+
The Nutrient DWS API automatically converts Office documents (DOCX, XLSX, PPTX) to PDF when processing them. This means:
8+
9+
- **No explicit conversion needed** - Just pass your Office documents to any method
10+
- **All methods accept Office documents** - `rotate_pages()`, `ocr_pdf()`, etc. work with DOCX files
11+
- **Seamless operation chaining** - Convert and process in one API call
12+
13+
### Example:
14+
```python
15+
# This automatically converts DOCX to PDF and rotates it!
16+
client.rotate_pages("document.docx", degrees=90)
17+
18+
# Merge PDFs and Office documents together
19+
client.merge_pdfs(["file1.pdf", "file2.docx", "spreadsheet.xlsx"])
20+
```
21+
522
## Direct API Methods
623

724
The following methods are available on the `NutrientClient` instance:
825

9-
### 1. `flatten_annotations(input_file, output_path=None)`
26+
### 1. `convert_to_pdf(input_file, output_path=None)`
27+
Converts Office documents to PDF format using implicit conversion.
28+
29+
**Parameters:**
30+
- `input_file`: Office document (DOCX, XLSX, PPTX)
31+
- `output_path`: Optional path to save output
32+
33+
**Example:**
34+
```python
35+
# Convert DOCX to PDF
36+
client.convert_to_pdf("document.docx", "document.pdf")
37+
38+
# Convert and get bytes
39+
pdf_bytes = client.convert_to_pdf("spreadsheet.xlsx")
40+
```
41+
42+
**Note:** HTML files are not currently supported.
43+
44+
### 2. `flatten_annotations(input_file, output_path=None)`
1045
Flattens all annotations and form fields in a PDF, converting them to static page content.
1146

1247
**Parameters:**
13-
- `input_file`: PDF file (path, bytes, or file-like object)
48+
- `input_file`: PDF or Office document
1449
- `output_path`: Optional path to save output
1550

1651
**Example:**
1752
```python
1853
client.flatten_annotations("document.pdf", "flattened.pdf")
54+
# Works with Office docs too!
55+
client.flatten_annotations("form.docx", "flattened.pdf")
1956
```
2057

21-
### 2. `rotate_pages(input_file, output_path=None, degrees=0, page_indexes=None)`
22-
Rotates pages in a PDF.
58+
### 3. `rotate_pages(input_file, output_path=None, degrees=0, page_indexes=None)`
59+
Rotates pages in a PDF or converts Office document to PDF and rotates.
2360

2461
**Parameters:**
25-
- `input_file`: PDF file
62+
- `input_file`: PDF or Office document
2663
- `output_path`: Optional output path
2764
- `degrees`: Rotation angle (90, 180, 270, or -90)
2865
- `page_indexes`: Optional list of page indexes to rotate (0-based)
@@ -32,15 +69,18 @@ Rotates pages in a PDF.
3269
# Rotate all pages 90 degrees
3370
client.rotate_pages("document.pdf", "rotated.pdf", degrees=90)
3471

72+
# Works with Office documents too!
73+
client.rotate_pages("presentation.pptx", "rotated.pdf", degrees=180)
74+
3575
# Rotate specific pages
3676
client.rotate_pages("document.pdf", "rotated.pdf", degrees=180, page_indexes=[0, 2])
3777
```
3878

39-
### 3. `ocr_pdf(input_file, output_path=None, language="english")`
40-
Applies OCR to make a PDF searchable.
79+
### 4. `ocr_pdf(input_file, output_path=None, language="english")`
80+
Applies OCR to make a PDF searchable. Converts Office documents to PDF first if needed.
4181

4282
**Parameters:**
43-
- `input_file`: PDF file
83+
- `input_file`: PDF or Office document
4484
- `output_path`: Optional output path
4585
- `language`: OCR language - supported values:
4686
- `"english"` or `"eng"` - English
@@ -49,13 +89,15 @@ Applies OCR to make a PDF searchable.
4989
**Example:**
5090
```python
5191
client.ocr_pdf("scanned.pdf", "searchable.pdf", language="english")
92+
# Convert DOCX to searchable PDF
93+
client.ocr_pdf("document.docx", "searchable.pdf", language="eng")
5294
```
5395

54-
### 4. `watermark_pdf(input_file, output_path=None, text=None, image_url=None, width=200, height=100, opacity=1.0, position="center")`
55-
Adds a watermark to all pages of a PDF.
96+
### 5. `watermark_pdf(input_file, output_path=None, text=None, image_url=None, width=200, height=100, opacity=1.0, position="center")`
97+
Adds a watermark to all pages of a PDF. Converts Office documents to PDF first if needed.
5698

5799
**Parameters:**
58-
- `input_file`: PDF file
100+
- `input_file`: PDF or Office document
59101
- `output_path`: Optional output path
60102
- `text`: Text for watermark (either text or image_url required)
61103
- `image_url`: URL of image for watermark
@@ -78,38 +120,46 @@ client.watermark_pdf(
78120
)
79121
```
80122

81-
### 5. `apply_redactions(input_file, output_path=None)`
82-
Applies redaction annotations to permanently remove content.
123+
### 6. `apply_redactions(input_file, output_path=None)`
124+
Applies redaction annotations to permanently remove content. Converts Office documents to PDF first if needed.
83125

84126
**Parameters:**
85-
- `input_file`: PDF file with redaction annotations
127+
- `input_file`: PDF or Office document with redaction annotations
86128
- `output_path`: Optional output path
87129

88130
**Example:**
89131
```python
90132
client.apply_redactions("document_with_redactions.pdf", "redacted.pdf")
91133
```
92134

93-
### 6. `merge_pdfs(input_files, output_path=None)`
94-
Merges multiple PDF files into one.
135+
### 7. `merge_pdfs(input_files, output_path=None)`
136+
Merges multiple files into one PDF. Automatically converts Office documents to PDF before merging.
95137

96138
**Parameters:**
97-
- `input_files`: List of PDF files to merge
139+
- `input_files`: List of files to merge (PDFs and/or Office documents)
98140
- `output_path`: Optional output path
99141

100142
**Example:**
101143
```python
144+
# Merge PDFs only
102145
client.merge_pdfs(
103146
["document1.pdf", "document2.pdf", "document3.pdf"],
104147
"merged.pdf"
105148
)
149+
150+
# Mix PDFs and Office documents - they'll be converted automatically!
151+
client.merge_pdfs(
152+
["report.pdf", "spreadsheet.xlsx", "presentation.pptx"],
153+
"combined.pdf"
154+
)
106155
```
107156

108157
## Builder API
109158

110-
The Builder API allows chaining multiple operations:
159+
The Builder API allows chaining multiple operations. Like the Direct API, it automatically converts Office documents to PDF when needed:
111160

112161
```python
162+
# Works with PDFs
113163
client.build(input_file="document.pdf") \
114164
.add_step("rotate-pages", {"degrees": 90}) \
115165
.add_step("ocr-pdf", {"language": "english"}) \
@@ -121,6 +171,12 @@ client.build(input_file="document.pdf") \
121171
}) \
122172
.add_step("flatten-annotations") \
123173
.execute(output_path="processed.pdf")
174+
175+
# Also works with Office documents!
176+
client.build(input_file="report.docx") \
177+
.add_step("watermark-pdf", {"text": "CONFIDENTIAL", "width": 300, "height": 150}) \
178+
.add_step("flatten-annotations") \
179+
.execute(output_path="watermarked_report.pdf")
124180
```
125181

126182
### Supported Builder Actions
@@ -135,7 +191,7 @@ client.build(input_file="document.pdf") \
135191

136192
The following operations are **NOT** currently supported by the API:
137193

138-
- Document conversion (Office to PDF, HTML to PDF)
194+
- HTML to PDF conversion (only Office documents are supported)
139195
- PDF to image export
140196
- PDF splitting
141197
- Form filling

src/nutrient/api/direct.py

Lines changed: 54 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ class DirectAPIMixin:
1818
These methods provide a simplified interface to common document
1919
processing operations. They internally use the Build API.
2020
21-
Note: Only operations actually supported by the API are included.
21+
Note: The API automatically converts supported document formats
22+
(DOCX, XLSX, PPTX) to PDF when processing.
2223
"""
2324

2425
def _process_file(
@@ -31,13 +32,42 @@ def _process_file(
3132
"""Process file method that will be provided by NutrientClient."""
3233
raise NotImplementedError("This method is provided by NutrientClient")
3334

35+
def convert_to_pdf(
36+
self,
37+
input_file: FileInput,
38+
output_path: Optional[str] = None,
39+
) -> Optional[bytes]:
40+
"""Convert a document to PDF.
41+
42+
Converts Office documents (DOCX, XLSX, PPTX) to PDF format.
43+
This uses the API's implicit conversion - simply uploading a
44+
non-PDF document returns it as a PDF.
45+
46+
Args:
47+
input_file: Input document (DOCX, XLSX, PPTX, etc).
48+
output_path: Optional path to save the output PDF.
49+
50+
Returns:
51+
Converted PDF as bytes, or None if output_path is provided.
52+
53+
Raises:
54+
AuthenticationError: If API key is missing or invalid.
55+
APIError: For other API errors (e.g., unsupported format).
56+
57+
Note:
58+
HTML files are not currently supported by the API.
59+
"""
60+
# Use builder with no actions - implicit conversion happens
61+
return self.build(input_file).execute(output_path) # type: ignore
62+
3463
def flatten_annotations(self, input_file: FileInput, output_path: Optional[str] = None) -> Optional[bytes]:
3564
"""Flatten annotations and form fields in a PDF.
3665
3766
Converts all annotations and form fields into static page content.
67+
If input is an Office document, it will be converted to PDF first.
3868
3969
Args:
40-
input_file: Input PDF file (path, bytes, or file-like object).
70+
input_file: Input file (PDF or Office document).
4171
output_path: Optional path to save the output file.
4272
4373
Returns:
@@ -59,9 +89,10 @@ def rotate_pages(
5989
"""Rotate pages in a PDF.
6090
6191
Rotate all pages or specific pages by the specified degrees.
92+
If input is an Office document, it will be converted to PDF first.
6293
6394
Args:
64-
input_file: Input PDF file (path, bytes, or file-like object).
95+
input_file: Input file (PDF or Office document).
6596
output_path: Optional path to save the output file.
6697
degrees: Rotation angle (90, 180, 270, or -90).
6798
page_indexes: Optional list of page indexes to rotate (0-based).
@@ -87,10 +118,11 @@ def ocr_pdf(
87118
"""Apply OCR to a PDF to make it searchable.
88119
89120
Performs optical character recognition on the PDF to extract text
90-
and make it searchable.
121+
and make it searchable. If input is an Office document, it will
122+
be converted to PDF first.
91123
92124
Args:
93-
input_file: Input PDF file (path, bytes, or file-like object).
125+
input_file: Input file (PDF or Office document).
94126
output_path: Optional path to save the output file.
95127
language: OCR language. Supported: "english", "eng", "deu", "german".
96128
Default is "english".
@@ -118,9 +150,10 @@ def watermark_pdf(
118150
"""Add a watermark to a PDF.
119151
120152
Adds a text or image watermark to all pages of the PDF.
153+
If input is an Office document, it will be converted to PDF first.
121154
122155
Args:
123-
input_file: Input PDF file (path, bytes, or file-like object).
156+
input_file: Input file (PDF or Office document).
124157
output_path: Optional path to save the output file.
125158
text: Text to use as watermark. Either text or image_url required.
126159
image_url: URL of image to use as watermark.
@@ -164,10 +197,11 @@ def apply_redactions(
164197
"""Apply redaction annotations to permanently remove content.
165198
166199
Applies any redaction annotations in the PDF to permanently remove
167-
the underlying content.
200+
the underlying content. If input is an Office document, it will
201+
be converted to PDF first.
168202
169203
Args:
170-
input_file: Input PDF file (path, bytes, or file-like object).
204+
input_file: Input file (PDF or Office document).
171205
output_path: Optional path to save the output file.
172206
173207
Returns:
@@ -186,10 +220,12 @@ def merge_pdfs(
186220
) -> Optional[bytes]:
187221
"""Merge multiple PDF files into one.
188222
189-
Combines multiple PDF files into a single PDF in the order provided.
223+
Combines multiple files into a single PDF in the order provided.
224+
Office documents (DOCX, XLSX, PPTX) will be automatically converted
225+
to PDF before merging.
190226
191227
Args:
192-
input_files: List of input PDF files (paths, bytes, or file-like objects).
228+
input_files: List of input files (PDFs or Office documents).
193229
output_path: Optional path to save the output file.
194230
195231
Returns:
@@ -199,6 +235,14 @@ def merge_pdfs(
199235
AuthenticationError: If API key is missing or invalid.
200236
APIError: For other API errors.
201237
ValueError: If less than 2 files provided.
238+
239+
Example:
240+
# Merge PDFs and Office documents
241+
client.merge_pdfs([
242+
"document1.pdf",
243+
"document2.docx",
244+
"spreadsheet.xlsx"
245+
], "merged.pdf")
202246
"""
203247
if len(input_files) < 2:
204248
raise ValueError("At least 2 files required for merge")

0 commit comments

Comments
 (0)