Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
127 changes: 127 additions & 0 deletions src/pdfrest/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,12 @@
PdfCompressPayload,
PdfDecryptPayload,
PdfEncryptPayload,
PdfExportFormDataPayload,
PdfFlattenAnnotationsPayload,
PdfFlattenFormsPayload,
PdfFlattenLayersPayload,
PdfFlattenTransparenciesPayload,
PdfImportFormDataPayload,
PdfInfoPayload,
PdfLinearizePayload,
PdfMergePayload,
Expand Down Expand Up @@ -127,6 +129,7 @@
ALL_PDF_INFO_QUERIES,
BmpColorModel,
CompressionLevel,
ExportDataFormat,
ExtractTextGranularity,
FlattenQuality,
GifColorModel,
Expand Down Expand Up @@ -2846,6 +2849,68 @@ def convert_to_word(
timeout=timeout,
)

def import_form_data(
self,
file: PdfRestFile | Sequence[PdfRestFile],
data_file: PdfRestFile | Sequence[PdfRestFile],
*,
output: str | None = None,
extra_query: Query | None = None,
extra_headers: AnyMapping | None = None,
extra_body: Body | None = None,
timeout: TimeoutTypes | None = None,
) -> PdfRestFileBasedResponse:
"""Import form data from a data file into an existing PDF with form fields."""

payload: dict[str, Any] = {"files": file, "data_file": data_file}
if output is not None:
payload["output"] = output

return self._post_file_operation(
endpoint="/pdf-with-imported-form-data",
payload=payload,
payload_model=PdfImportFormDataPayload,
extra_query=extra_query,
extra_headers=extra_headers,
extra_body=extra_body,
timeout=timeout,
)

def export_form_data(
self,
file: PdfRestFile | Sequence[PdfRestFile],
*,
data_format: ExportDataFormat,
output: str | None = None,
extra_query: Query | None = None,
extra_headers: AnyMapping | None = None,
extra_body: Body | None = None,
timeout: TimeoutTypes | None = None,
) -> PdfRestFileBasedResponse:
"""Export form data from a PDF into an external data file.

`data_format` support depends on detected form type:
- AcroForm PDFs: `xfdf`, `fdf`, `xml`
- XFA PDFs: `xfd`, `xdp`, `xml`
"""

payload: dict[str, Any] = {
"files": file,
"data_format": data_format,
}
if output is not None:
payload["output"] = output

return self._post_file_operation(
endpoint="/exported-form-data",
payload=payload,
payload_model=PdfExportFormDataPayload,
extra_query=extra_query,
extra_headers=extra_headers,
extra_body=extra_body,
timeout=timeout,
)

def flatten_pdf_forms(
self,
file: PdfRestFile | Sequence[PdfRestFile],
Expand Down Expand Up @@ -4549,6 +4614,68 @@ async def convert_to_word(
timeout=timeout,
)

async def import_form_data(
self,
file: PdfRestFile | Sequence[PdfRestFile],
data_file: PdfRestFile | Sequence[PdfRestFile],
*,
output: str | None = None,
extra_query: Query | None = None,
extra_headers: AnyMapping | None = None,
extra_body: Body | None = None,
timeout: TimeoutTypes | None = None,
) -> PdfRestFileBasedResponse:
"""Asynchronously import form data from a data file into a PDF."""

payload: dict[str, Any] = {"files": file, "data_file": data_file}
if output is not None:
payload["output"] = output

return await self._post_file_operation(
endpoint="/pdf-with-imported-form-data",
payload=payload,
payload_model=PdfImportFormDataPayload,
extra_query=extra_query,
extra_headers=extra_headers,
extra_body=extra_body,
timeout=timeout,
)

async def export_form_data(
self,
file: PdfRestFile | Sequence[PdfRestFile],
*,
data_format: ExportDataFormat,
output: str | None = None,
extra_query: Query | None = None,
extra_headers: AnyMapping | None = None,
extra_body: Body | None = None,
timeout: TimeoutTypes | None = None,
) -> PdfRestFileBasedResponse:
"""Asynchronously export form data from a PDF into a data file.

`data_format` support depends on detected form type:
- AcroForm PDFs: `xfdf`, `fdf`, `xml`
- XFA PDFs: `xfd`, `xdp`, `xml`
"""

payload: dict[str, Any] = {
"files": file,
"data_format": data_format,
}
if output is not None:
payload["output"] = output

return await self._post_file_operation(
endpoint="/exported-form-data",
payload=payload,
payload_model=PdfExportFormDataPayload,
extra_query=extra_query,
extra_headers=extra_headers,
extra_body=extra_body,
timeout=timeout,
)

async def flatten_pdf_forms(
self,
file: PdfRestFile | Sequence[PdfRestFile],
Expand Down
75 changes: 75 additions & 0 deletions src/pdfrest/models/_internal.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
from pdfrest.types.public import PdfRedactionPreset

from ..types import (
ExportDataFormat,
HtmlPageOrientation,
HtmlPageSize,
HtmlWebLayout,
Expand Down Expand Up @@ -1318,6 +1319,80 @@ class PdfFlattenFormsPayload(BaseModel):
] = None


class PdfImportFormDataPayload(BaseModel):
"""Adapt caller options into a pdfRest-ready import-form-data request payload."""

files: Annotated[
list[PdfRestFile],
Field(
min_length=1,
max_length=1,
validation_alias=AliasChoices("file", "files"),
serialization_alias="id",
),
BeforeValidator(_ensure_list),
AfterValidator(
_allowed_mime_types("application/pdf", error_msg="Must be a PDF file")
),
PlainSerializer(_serialize_as_first_file_id),
]
data_file: Annotated[
list[PdfRestFile],
Field(
min_length=1,
max_length=1,
validation_alias=AliasChoices("data_file", "data_files"),
serialization_alias="data_file_id",
),
BeforeValidator(_ensure_list),
AfterValidator(
_allowed_mime_types(
"application/xml",
"text/xml",
"application/vnd.fdf",
"application/vnd.adobe.xfdf",
"application/vnd.adobe.xdp+xml",
"application/vnd.adobe.xfd+xml",
error_msg="Data file must be an XFDF, XDP, XFD, FDF, or XML file",
)
),
PlainSerializer(_serialize_as_first_file_id),
]
output: Annotated[
str | None,
Field(serialization_alias="output", min_length=1, default=None),
AfterValidator(_validate_output_prefix),
] = None


class PdfExportFormDataPayload(BaseModel):
"""Adapt caller options into a pdfRest-ready export-form-data request payload."""

files: Annotated[
list[PdfRestFile],
Field(
min_length=1,
max_length=1,
validation_alias=AliasChoices("file", "files"),
serialization_alias="id",
),
BeforeValidator(_ensure_list),
AfterValidator(
_allowed_mime_types("application/pdf", error_msg="Must be a PDF file")
),
PlainSerializer(_serialize_as_first_file_id),
]
data_format: Annotated[
ExportDataFormat,
Field(serialization_alias="data_format"),
]
output: Annotated[
str | None,
Field(serialization_alias="output", min_length=1, default=None),
AfterValidator(_validate_output_prefix),
] = None


class PdfCompressPayload(BaseModel):
"""Adapt caller options into a pdfRest-ready compress request payload."""

Expand Down
2 changes: 2 additions & 0 deletions src/pdfrest/types/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
ALL_PDF_RESTRICTIONS,
BmpColorModel,
CompressionLevel,
ExportDataFormat,
ExtractTextGranularity,
FlattenQuality,
GifColorModel,
Expand Down Expand Up @@ -48,6 +49,7 @@
"ALL_PDF_RESTRICTIONS",
"BmpColorModel",
"CompressionLevel",
"ExportDataFormat",
"ExtractTextGranularity",
"FlattenQuality",
"GifColorModel",
Expand Down
4 changes: 4 additions & 0 deletions src/pdfrest/types/public.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"ALL_PDF_RESTRICTIONS",
"BmpColorModel",
"CompressionLevel",
"ExportDataFormat",
"ExtractTextGranularity",
"FlattenQuality",
"GifColorModel",
Expand Down Expand Up @@ -167,6 +168,9 @@ class PdfMergeSource(TypedDict, total=False):
JpegColorModel = Literal["rgb", "cmyk", "gray"]
TiffColorModel = Literal["rgb", "rgba", "cmyk", "lab", "gray"]
GraphicSmoothing = Literal["none", "all", "text", "line", "image"]
# Server accepts all values here, but enforces form-type subsets at runtime:
# AcroForm -> xfdf/fdf/xml, XFA -> xfd/xdp/xml.
ExportDataFormat = Literal["fdf", "xfdf", "xml", "xdp", "xfd"]

SummaryFormat = Literal[
"overview",
Expand Down
Loading