Skip to content

Commit 7f175dc

Browse files
Merge pull request #4 from datalogics-cgreen/pdfcloud-5463-three
PDFCLOUD-5463 Add PDF/X, Flatten Forms, and Word
2 parents 0e28699 + 95ca18b commit 7f175dc

7 files changed

Lines changed: 690 additions & 1 deletion

File tree

src/pdfrest/client.py

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,12 +73,15 @@
7373
BmpPdfRestPayload,
7474
GifPdfRestPayload,
7575
JpegPdfRestPayload,
76+
PdfFlattenFormsPayload,
7677
PdfInfoPayload,
7778
PdfMergePayload,
7879
PdfRedactionApplyPayload,
7980
PdfRedactionPreviewPayload,
8081
PdfRestRawFileResponse,
8182
PdfSplitPayload,
83+
PdfToPdfxPayload,
84+
PdfToWordPayload,
8285
PngPdfRestPayload,
8386
TiffPdfRestPayload,
8487
UploadURLs,
@@ -90,6 +93,7 @@
9093
PdfPageSelection,
9194
PdfRedactionInstruction,
9295
PdfRGBColor,
96+
PdfXType,
9397
)
9498

9599
DEFAULT_BASE_URL = "https://api.pdfrest.com"
@@ -2141,6 +2145,85 @@ def merge_pdfs(
21412145
timeout=timeout,
21422146
)
21432147

2148+
def convert_to_word(
2149+
self,
2150+
file: PdfRestFile | Sequence[PdfRestFile],
2151+
*,
2152+
output: str | None = None,
2153+
extra_query: Query | None = None,
2154+
extra_headers: AnyMapping | None = None,
2155+
extra_body: Body | None = None,
2156+
timeout: TimeoutTypes | None = None,
2157+
) -> PdfRestFileBasedResponse:
2158+
"""Convert a PDF to a Word document."""
2159+
2160+
payload: dict[str, Any] = {"files": file}
2161+
if output is not None:
2162+
payload["output"] = output
2163+
2164+
return self._post_file_operation(
2165+
endpoint="/word",
2166+
payload=payload,
2167+
payload_model=PdfToWordPayload,
2168+
extra_query=extra_query,
2169+
extra_headers=extra_headers,
2170+
extra_body=extra_body,
2171+
timeout=timeout,
2172+
)
2173+
2174+
def flatten_pdf_forms(
2175+
self,
2176+
file: PdfRestFile | Sequence[PdfRestFile],
2177+
*,
2178+
output: str | None = None,
2179+
extra_query: Query | None = None,
2180+
extra_headers: AnyMapping | None = None,
2181+
extra_body: Body | None = None,
2182+
timeout: TimeoutTypes | None = None,
2183+
) -> PdfRestFileBasedResponse:
2184+
"""Flatten form fields in a PDF so they are no longer editable."""
2185+
2186+
payload: dict[str, Any] = {"files": file}
2187+
if output is not None:
2188+
payload["output"] = output
2189+
2190+
return self._post_file_operation(
2191+
endpoint="/flattened-forms-pdf",
2192+
payload=payload,
2193+
payload_model=PdfFlattenFormsPayload,
2194+
extra_query=extra_query,
2195+
extra_headers=extra_headers,
2196+
extra_body=extra_body,
2197+
timeout=timeout,
2198+
)
2199+
2200+
def convert_to_pdfx(
2201+
self,
2202+
file: PdfRestFile | Sequence[PdfRestFile],
2203+
*,
2204+
output_type: PdfXType,
2205+
output: str | None = None,
2206+
extra_query: Query | None = None,
2207+
extra_headers: AnyMapping | None = None,
2208+
extra_body: Body | None = None,
2209+
timeout: TimeoutTypes | None = None,
2210+
) -> PdfRestFileBasedResponse:
2211+
"""Convert a PDF to a specified PDF/X version."""
2212+
2213+
payload: dict[str, Any] = {"files": file, "output_type": output_type}
2214+
if output is not None:
2215+
payload["output"] = output
2216+
2217+
return self._post_file_operation(
2218+
endpoint="/pdfx",
2219+
payload=payload,
2220+
payload_model=PdfToPdfxPayload,
2221+
extra_query=extra_query,
2222+
extra_headers=extra_headers,
2223+
extra_body=extra_body,
2224+
timeout=timeout,
2225+
)
2226+
21442227
def convert_to_png(
21452228
self,
21462229
files: PdfRestFile | Sequence[PdfRestFile],
@@ -2572,6 +2655,85 @@ async def merge_pdfs(
25722655
timeout=timeout,
25732656
)
25742657

2658+
async def convert_to_word(
2659+
self,
2660+
file: PdfRestFile | Sequence[PdfRestFile],
2661+
*,
2662+
output: str | None = None,
2663+
extra_query: Query | None = None,
2664+
extra_headers: AnyMapping | None = None,
2665+
extra_body: Body | None = None,
2666+
timeout: TimeoutTypes | None = None,
2667+
) -> PdfRestFileBasedResponse:
2668+
"""Asynchronously convert a PDF to a Word document."""
2669+
2670+
payload: dict[str, Any] = {"files": file}
2671+
if output is not None:
2672+
payload["output"] = output
2673+
2674+
return await self._post_file_operation(
2675+
endpoint="/word",
2676+
payload=payload,
2677+
payload_model=PdfToWordPayload,
2678+
extra_query=extra_query,
2679+
extra_headers=extra_headers,
2680+
extra_body=extra_body,
2681+
timeout=timeout,
2682+
)
2683+
2684+
async def flatten_pdf_forms(
2685+
self,
2686+
file: PdfRestFile | Sequence[PdfRestFile],
2687+
*,
2688+
output: str | None = None,
2689+
extra_query: Query | None = None,
2690+
extra_headers: AnyMapping | None = None,
2691+
extra_body: Body | None = None,
2692+
timeout: TimeoutTypes | None = None,
2693+
) -> PdfRestFileBasedResponse:
2694+
"""Asynchronously flatten form fields in a PDF."""
2695+
2696+
payload: dict[str, Any] = {"files": file}
2697+
if output is not None:
2698+
payload["output"] = output
2699+
2700+
return await self._post_file_operation(
2701+
endpoint="/flattened-forms-pdf",
2702+
payload=payload,
2703+
payload_model=PdfFlattenFormsPayload,
2704+
extra_query=extra_query,
2705+
extra_headers=extra_headers,
2706+
extra_body=extra_body,
2707+
timeout=timeout,
2708+
)
2709+
2710+
async def convert_to_pdfx(
2711+
self,
2712+
file: PdfRestFile | Sequence[PdfRestFile],
2713+
*,
2714+
output_type: PdfXType,
2715+
output: str | None = None,
2716+
extra_query: Query | None = None,
2717+
extra_headers: AnyMapping | None = None,
2718+
extra_body: Body | None = None,
2719+
timeout: TimeoutTypes | None = None,
2720+
) -> PdfRestFileBasedResponse:
2721+
"""Asynchronously convert a PDF to a specified PDF/X version."""
2722+
2723+
payload: dict[str, Any] = {"files": file, "output_type": output_type}
2724+
if output is not None:
2725+
payload["output"] = output
2726+
2727+
return await self._post_file_operation(
2728+
endpoint="/pdfx",
2729+
payload=payload,
2730+
payload_model=PdfToPdfxPayload,
2731+
extra_query=extra_query,
2732+
extra_headers=extra_headers,
2733+
extra_body=extra_body,
2734+
timeout=timeout,
2735+
)
2736+
25752737
async def convert_to_png(
25762738
self,
25772739
files: PdfRestFile | Sequence[PdfRestFile],

src/pdfrest/models/_internal.py

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222
from pdfrest.types.public import PdfRedactionPreset
2323

24-
from ..types import PdfInfoQuery
24+
from ..types import PdfInfoQuery, PdfXType
2525
from . import PdfRestFile
2626
from .public import PdfRestFileID
2727

@@ -476,6 +476,79 @@ def _serialize_pdf_merge_payload(
476476
return payload
477477

478478

479+
class PdfToWordPayload(BaseModel):
480+
"""Adapt caller options into a pdfRest-ready Word request payload."""
481+
482+
files: Annotated[
483+
list[PdfRestFile],
484+
Field(
485+
min_length=1,
486+
max_length=1,
487+
validation_alias=AliasChoices("file", "files"),
488+
serialization_alias="id",
489+
),
490+
BeforeValidator(_ensure_list),
491+
AfterValidator(
492+
_allowed_mime_types("application/pdf", error_msg="Must be a PDF file")
493+
),
494+
PlainSerializer(_serialize_as_first_file_id),
495+
]
496+
output: Annotated[
497+
str | None,
498+
Field(serialization_alias="output", min_length=1, default=None),
499+
AfterValidator(_validate_output_prefix),
500+
] = None
501+
502+
503+
class PdfToPdfxPayload(BaseModel):
504+
"""Adapt caller options into a pdfRest-ready PDF/X request payload."""
505+
506+
files: Annotated[
507+
list[PdfRestFile],
508+
Field(
509+
min_length=1,
510+
max_length=1,
511+
validation_alias=AliasChoices("file", "files"),
512+
serialization_alias="id",
513+
),
514+
BeforeValidator(_ensure_list),
515+
AfterValidator(
516+
_allowed_mime_types("application/pdf", error_msg="Must be a PDF file")
517+
),
518+
PlainSerializer(_serialize_as_first_file_id),
519+
]
520+
output_type: Annotated[PdfXType, Field(serialization_alias="output_type")]
521+
output: Annotated[
522+
str | None,
523+
Field(serialization_alias="output", min_length=1, default=None),
524+
AfterValidator(_validate_output_prefix),
525+
] = None
526+
527+
528+
class PdfFlattenFormsPayload(BaseModel):
529+
"""Adapt caller options into a pdfRest-ready flatten-forms request payload."""
530+
531+
files: Annotated[
532+
list[PdfRestFile],
533+
Field(
534+
min_length=1,
535+
max_length=1,
536+
validation_alias=AliasChoices("file", "files"),
537+
serialization_alias="id",
538+
),
539+
BeforeValidator(_ensure_list),
540+
AfterValidator(
541+
_allowed_mime_types("application/pdf", error_msg="Must be a PDF file")
542+
),
543+
PlainSerializer(_serialize_as_first_file_id),
544+
]
545+
output: Annotated[
546+
str | None,
547+
Field(serialization_alias="output", min_length=1, default=None),
548+
AfterValidator(_validate_output_prefix),
549+
] = None
550+
551+
479552
class BmpPdfRestPayload(BasePdfRestGraphicPayload[Literal["rgb", "gray"]]):
480553
"""Adapt caller options into a pdfRest-ready BMP request payload."""
481554

src/pdfrest/types/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
PdfRedactionPreset,
1111
PdfRedactionType,
1212
PdfRGBColor,
13+
PdfXType,
1314
)
1415

1516
__all__ = [
@@ -22,4 +23,5 @@
2223
"PdfRedactionInstruction",
2324
"PdfRedactionPreset",
2425
"PdfRedactionType",
26+
"PdfXType",
2527
]

src/pdfrest/types/public.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
"PdfRedactionInstruction",
2323
"PdfRedactionPreset",
2424
"PdfRedactionType",
25+
"PdfXType",
2526
)
2627

2728
PdfInfoQuery = Literal[
@@ -96,3 +97,5 @@ class PdfMergeSource(TypedDict, total=False):
9697

9798

9899
PdfMergeInput = PdfRestFile | PdfMergeSource | tuple[PdfRestFile, PdfPageSelection]
100+
101+
PdfXType = Literal["PDF/X-1a", "PDF/X-3", "PDF/X-4", "PDF/X-6"]

0 commit comments

Comments
 (0)