Skip to content

Commit c16b0c3

Browse files
Add Flatten Transparencies
Assisted-by: Codex
1 parent 08bb5e9 commit c16b0c3

4 files changed

Lines changed: 490 additions & 0 deletions

File tree

src/pdfrest/client.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@
8888
PdfRedactionApplyPayload,
8989
PdfRedactionPreviewPayload,
9090
PdfRestRawFileResponse,
91+
PdfFlattenTransparenciesPayload,
9192
PdfSplitPayload,
9293
PdfToExcelPayload,
9394
PdfToPdfxPayload,
@@ -2552,6 +2553,33 @@ def flatten_pdf_forms(
25522553
timeout=timeout,
25532554
)
25542555

2556+
def flatten_transparencies(
2557+
self,
2558+
file: PdfRestFile | Sequence[PdfRestFile],
2559+
*,
2560+
output: str | None = None,
2561+
quality: Literal["low", "medium", "high"] = "medium",
2562+
extra_query: Query | None = None,
2563+
extra_headers: AnyMapping | None = None,
2564+
extra_body: Body | None = None,
2565+
timeout: TimeoutTypes | None = None,
2566+
) -> PdfRestFileBasedResponse:
2567+
"""Flatten transparent objects in a PDF."""
2568+
2569+
payload: dict[str, Any] = {"files": file, "quality": quality}
2570+
if output is not None:
2571+
payload["output"] = output
2572+
2573+
return self._post_file_operation(
2574+
endpoint="/flattened-transparencies-pdf",
2575+
payload=payload,
2576+
payload_model=PdfFlattenTransparenciesPayload,
2577+
extra_query=extra_query,
2578+
extra_headers=extra_headers,
2579+
extra_body=extra_body,
2580+
timeout=timeout,
2581+
)
2582+
25552583
def linearize_pdf(
25562584
self,
25572585
file: PdfRestFile | Sequence[PdfRestFile],
@@ -3425,6 +3453,33 @@ async def flatten_pdf_forms(
34253453
timeout=timeout,
34263454
)
34273455

3456+
async def flatten_transparencies(
3457+
self,
3458+
file: PdfRestFile | Sequence[PdfRestFile],
3459+
*,
3460+
output: str | None = None,
3461+
quality: Literal["low", "medium", "high"] = "medium",
3462+
extra_query: Query | None = None,
3463+
extra_headers: AnyMapping | None = None,
3464+
extra_body: Body | None = None,
3465+
timeout: TimeoutTypes | None = None,
3466+
) -> PdfRestFileBasedResponse:
3467+
"""Asynchronously flatten transparent objects in a PDF."""
3468+
3469+
payload: dict[str, Any] = {"files": file, "quality": quality}
3470+
if output is not None:
3471+
payload["output"] = output
3472+
3473+
return await self._post_file_operation(
3474+
endpoint="/flattened-transparencies-pdf",
3475+
payload=payload,
3476+
payload_model=PdfFlattenTransparenciesPayload,
3477+
extra_query=extra_query,
3478+
extra_headers=extra_headers,
3479+
extra_body=extra_body,
3480+
timeout=timeout,
3481+
)
3482+
34283483
async def linearize_pdf(
34293484
self,
34303485
file: PdfRestFile | Sequence[PdfRestFile],

src/pdfrest/models/_internal.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -889,6 +889,31 @@ class PdfLinearizePayload(BaseModel):
889889
] = None
890890

891891

892+
class PdfFlattenTransparenciesPayload(BaseModel):
893+
"""Adapt caller options into a pdfRest-ready flatten-transparencies request payload."""
894+
895+
files: Annotated[
896+
list[PdfRestFile],
897+
Field(
898+
min_length=1,
899+
max_length=1,
900+
validation_alias=AliasChoices("file", "files"),
901+
serialization_alias="id",
902+
),
903+
BeforeValidator(_ensure_list),
904+
AfterValidator(
905+
_allowed_mime_types("application/pdf", error_msg="Must be a PDF file")
906+
),
907+
PlainSerializer(_serialize_as_first_file_id),
908+
]
909+
output: Annotated[
910+
str | None,
911+
Field(serialization_alias="output", min_length=1, default=None),
912+
AfterValidator(_validate_output_prefix),
913+
] = None
914+
quality: Literal["low", "medium", "high"] = "medium"
915+
916+
892917
class BmpPdfRestPayload(BasePdfRestGraphicPayload[Literal["rgb", "gray"]]):
893918
"""Adapt caller options into a pdfRest-ready BMP request payload."""
894919

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
from __future__ import annotations
2+
3+
import pytest
4+
5+
from pdfrest import AsyncPdfRestClient, PdfRestApiError, PdfRestClient
6+
from pdfrest.models import PdfRestFile
7+
8+
from ..resources import get_test_resource_path
9+
10+
11+
@pytest.fixture(scope="module")
12+
def uploaded_pdf_for_transparencies(
13+
pdfrest_api_key: str,
14+
pdfrest_live_base_url: str,
15+
) -> PdfRestFile:
16+
resource = get_test_resource_path("report.pdf")
17+
with PdfRestClient(
18+
api_key=pdfrest_api_key,
19+
base_url=pdfrest_live_base_url,
20+
) as client:
21+
return client.files.create_from_paths([resource])[0]
22+
23+
24+
@pytest.mark.parametrize(
25+
"output_name,quality",
26+
[
27+
pytest.param(None, "medium", id="default-output"),
28+
pytest.param("flatten-transparency", "high", id="custom-output-high"),
29+
],
30+
)
31+
def test_live_flatten_transparencies_success(
32+
pdfrest_api_key: str,
33+
pdfrest_live_base_url: str,
34+
uploaded_pdf_for_transparencies: PdfRestFile,
35+
output_name: str | None,
36+
quality: str,
37+
) -> None:
38+
kwargs: dict[str, str] = {"quality": quality}
39+
if output_name is not None:
40+
kwargs["output"] = output_name
41+
42+
with PdfRestClient(
43+
api_key=pdfrest_api_key,
44+
base_url=pdfrest_live_base_url,
45+
) as client:
46+
response = client.flatten_transparencies(
47+
uploaded_pdf_for_transparencies, **kwargs
48+
)
49+
50+
assert response.output_files
51+
output_file = response.output_file
52+
assert output_file.type == "application/pdf"
53+
assert str(response.input_id) == str(uploaded_pdf_for_transparencies.id)
54+
if output_name is not None:
55+
assert output_file.name.startswith(output_name)
56+
else:
57+
assert output_file.name.endswith(".pdf")
58+
59+
60+
@pytest.mark.asyncio
61+
async def test_live_async_flatten_transparencies_success(
62+
pdfrest_api_key: str,
63+
pdfrest_live_base_url: str,
64+
uploaded_pdf_for_transparencies: PdfRestFile,
65+
) -> None:
66+
async with AsyncPdfRestClient(
67+
api_key=pdfrest_api_key,
68+
base_url=pdfrest_live_base_url,
69+
) as client:
70+
response = await client.flatten_transparencies(
71+
uploaded_pdf_for_transparencies, output="async", quality="low"
72+
)
73+
74+
assert response.output_files
75+
output_file = response.output_file
76+
assert output_file.name.startswith("async")
77+
assert output_file.type == "application/pdf"
78+
assert str(response.input_id) == str(uploaded_pdf_for_transparencies.id)
79+
80+
81+
def test_live_flatten_transparencies_invalid_file_id(
82+
pdfrest_api_key: str,
83+
pdfrest_live_base_url: str,
84+
uploaded_pdf_for_transparencies: PdfRestFile,
85+
) -> None:
86+
with (
87+
PdfRestClient(
88+
api_key=pdfrest_api_key,
89+
base_url=pdfrest_live_base_url,
90+
) as client,
91+
pytest.raises(PdfRestApiError),
92+
):
93+
client.flatten_transparencies(
94+
uploaded_pdf_for_transparencies,
95+
extra_body={"id": "00000000-0000-0000-0000-000000000000"},
96+
)
97+
98+
99+
@pytest.mark.asyncio
100+
async def test_live_async_flatten_transparencies_invalid_file_id(
101+
pdfrest_api_key: str,
102+
pdfrest_live_base_url: str,
103+
uploaded_pdf_for_transparencies: PdfRestFile,
104+
) -> None:
105+
async with AsyncPdfRestClient(
106+
api_key=pdfrest_api_key,
107+
base_url=pdfrest_live_base_url,
108+
) as client:
109+
with pytest.raises(PdfRestApiError):
110+
await client.flatten_transparencies(
111+
uploaded_pdf_for_transparencies,
112+
extra_body={"id": "ffffffff-ffff-ffff-ffff-ffffffffffff"},
113+
)

0 commit comments

Comments
 (0)