Skip to content

Commit

Permalink
Moves where the options are located, centralizing them
Browse files Browse the repository at this point in the history
  • Loading branch information
stumpylog committed Oct 14, 2023
1 parent 4f4b1c9 commit d3684ab
Show file tree
Hide file tree
Showing 11 changed files with 121 additions and 120 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,22 +74,22 @@ with GotenbergClient("http://localhost:3000") as client:
Converting an HTML file with additional resources into a PDF/A1a format:

```python
from gotenberg_client.pdf_format import PdfAFormatOptions
from gotenberg_client.options import PdfAFormat

with GotenbergClient("http://localhost:3000") as client:
with client.chromium.html_to_pdf() as route:
response = route.index("my-index.html").resource("image.png").resource("style.css").pdf_format(PdfAFormatOptions.A1a).run()
response = route.index("my-index.html").resource("image.png").resource("style.css").pdf_format(PdfAFormat.A1a).run()
Path("my-index.pdf").write_bytes(response.content)
```

Converting a URL into PDF, in landscape format

```python
from gotenberg_client.convert.common import PageOrientationOptions
from gotenberg_client.options import PageOrientation

with GotenbergClient("http://localhost:3000") as client:
with client.chromium.html_to_pdf() as route:
response = route.url("https://hello.world").orient(PageOrientationOptions.Landscape).run()
response = route.url("https://hello.world").orient(PageOrientation.Landscape).run()
Path("my-world.pdf").write_bytes(response.content)
```

Expand Down
4 changes: 2 additions & 2 deletions src/gotenberg_client/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from httpx import Response
from httpx._types import RequestFiles

from gotenberg_client.pdf_format import PdfAFormatOptions
from gotenberg_client.options import PdfAFormat

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -102,7 +102,7 @@ def _add_file_map(self, filepath: Path, name: Optional[str] = None) -> None:
logger.warning(f"{name} has already been provided, overwriting anyway")
self._file_map[name] = filepath

def pdf_format(self, pdf_format: PdfAFormatOptions) -> "BaseRoute":
def pdf_format(self, pdf_format: PdfAFormat) -> "BaseRoute":
"""
All routes provide the option to configure the output PDF as a
PDF/A format
Expand Down
54 changes: 10 additions & 44 deletions src/gotenberg_client/convert/chromium.py
Original file line number Diff line number Diff line change
@@ -1,35 +1,30 @@
# SPDX-FileCopyrightText: 2023-present Trenton H <[email protected]>
#
# SPDX-License-Identifier: MPL-2.0
import dataclasses
import enum
import json
import logging
from pathlib import Path
from typing import Dict
from typing import Final
from typing import List
from typing import Optional
from typing import Union

from gotenberg_client.base import BaseApi
from gotenberg_client.convert.common import FORCE_MULTIPART
from gotenberg_client.convert.common import ConvertBaseRoute
from gotenberg_client.convert.common import ForceMultipartDict
from gotenberg_client.convert.common import optional_to_form
from gotenberg_client.options import EmulatedMediaType
from gotenberg_client.options import Margin
from gotenberg_client.options import PageSize

logger = logging.getLogger()


@dataclasses.dataclass
class PageSize:
width: Optional[Union[float, int]] = None
height: Optional[Union[float, int]] = None
# See https://github.com/psf/requests/issues/1081#issuecomment-428504128
class ForceMultipartDict(Dict):
def __bool__(self) -> bool:
return True

def to_form(self) -> Dict[str, str]:
data = optional_to_form(self.width, "paperWidth")
data.update(optional_to_form(self.height, "paperHeight"))
return data

FORCE_MULTIPART: Final = ForceMultipartDict()


# Define common paper sizes as shortcuts
Expand All @@ -46,40 +41,11 @@ def to_form(self) -> Dict[str, str]:
Ledge: Final = PageSize(width=17, height=11)


@dataclasses.dataclass
class Margin:
top: Optional[Union[float, int]] = None
bottom: Optional[Union[float, int]] = None
left: Optional[Union[float, int]] = None
right: Optional[Union[float, int]] = None

def to_form(self) -> Dict[str, str]:
data = optional_to_form(self.top, "marginTop")
data.update(optional_to_form(self.bottom, "marginBottom"))
data.update(optional_to_form(self.left, "marginLeft"))
data.update(optional_to_form(self.right, "marginRight"))
return data


Gotenberg_Default_Margines: Final = Margin(0.39, 0.39, 0.39, 0.39)
Word_Default_Margins: Final = Margin(top=1.0, bottom=1.0, left=1.0, right=1.0)
Word_Narrow_Margins: Final = Margin(top=0.5, bottom=0.5, left=0.5, right=0.5)


@enum.unique
class EmulatedMediaTypeChoices(str, enum.Enum):
Print = enum.auto()
Screen = enum.auto()

def to_form(self) -> Dict[str, str]:
if self.value == EmulatedMediaTypeChoices.Print.value:
return {"emulatedMediaType": "print"}
elif self.value == EmulatedMediaTypeChoices.Screen.value:
return {"emulatedMediaType": "screen"}
else: # pragma: no cover
raise NotImplementedError(self.value)


class ChromiumBaseRoute(ConvertBaseRoute):
def header(self, header: Path) -> "ChromiumBaseRoute":
self._add_file_map(header, "header.html")
Expand Down Expand Up @@ -144,7 +110,7 @@ def render_expr(self, expr: str) -> "ChromiumBaseRoute":
self._form_data.update({"waitForExpression": expr})
return self

def media_type(self, media_type: EmulatedMediaTypeChoices) -> "ChromiumBaseRoute":
def media_type(self, media_type: EmulatedMediaType) -> "ChromiumBaseRoute":
self._form_data.update(media_type.to_form())
return self

Expand Down
28 changes: 2 additions & 26 deletions src/gotenberg_client/convert/common.py
Original file line number Diff line number Diff line change
@@ -1,44 +1,20 @@
# SPDX-FileCopyrightText: 2023-present Trenton H <[email protected]>
#
# SPDX-License-Identifier: MPL-2.0
import enum
import logging
from functools import lru_cache
from typing import Dict
from typing import Final
from typing import Optional
from typing import Union

from gotenberg_client.base import BaseRoute
from gotenberg_client.options import PageOrientation

logger = logging.getLogger()


# See https://github.com/psf/requests/issues/1081#issuecomment-428504128
class ForceMultipartDict(Dict):
def __bool__(self) -> bool:
return True


FORCE_MULTIPART: Final = ForceMultipartDict()


@enum.unique
class PageOrientationOptions(enum.Enum):
Landscape = enum.auto()
Potrait = enum.auto()

def to_form(self) -> Dict[str, str]:
if self.value == PageOrientationOptions.Landscape.value:
return {"landscape": "true"}
elif self.value == PageOrientationOptions.Potrait.value:
return {"landscape": "false"}
else: # pragma: no cover
raise NotImplementedError(self.value)


class ConvertBaseRoute(BaseRoute):
def orient(self, orient: PageOrientationOptions) -> "BaseRoute":
def orient(self, orient: PageOrientation) -> "BaseRoute":
self._form_data.update(orient.to_form())
return self

Expand Down
81 changes: 81 additions & 0 deletions src/gotenberg_client/options.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# SPDX-FileCopyrightText: 2023-present Trenton H <[email protected]>
#
# SPDX-License-Identifier: MPL-2.0
import dataclasses
import enum
from typing import Dict
from typing import Optional
from typing import Union

from gotenberg_client.convert.common import optional_to_form


@enum.unique
class PdfAFormat(enum.Enum):
A1a = enum.auto()
A2b = enum.auto()
A3b = enum.auto()

def to_form(self) -> Dict[str, str]:
if self.value == PdfAFormat.A1a.value:
return {"pdfFormat": "PDF/A-1a"}
elif self.value == PdfAFormat.A2b.value:
return {"pdfFormat": "PDF/A-2b"}
elif self.value == PdfAFormat.A3b.value:
return {"pdfFormat": "PDF/A-3b"}
else: # pragma: no cover
raise NotImplementedError(self.value)


@enum.unique
class PageOrientation(enum.Enum):
Landscape = enum.auto()
Potrait = enum.auto()

def to_form(self) -> Dict[str, str]:
if self.value == PageOrientation.Landscape.value:
return {"landscape": "true"}
elif self.value == PageOrientation.Potrait.value:
return {"landscape": "false"}
else: # pragma: no cover
raise NotImplementedError(self.value)


@dataclasses.dataclass
class PageSize:
width: Optional[Union[float, int]] = None
height: Optional[Union[float, int]] = None

def to_form(self) -> Dict[str, str]:
data = optional_to_form(self.width, "paperWidth")
data.update(optional_to_form(self.height, "paperHeight"))
return data


@dataclasses.dataclass
class Margin:
top: Optional[Union[float, int]] = None
bottom: Optional[Union[float, int]] = None
left: Optional[Union[float, int]] = None
right: Optional[Union[float, int]] = None

def to_form(self) -> Dict[str, str]:
data = optional_to_form(self.top, "marginTop")
data.update(optional_to_form(self.bottom, "marginBottom"))
data.update(optional_to_form(self.left, "marginLeft"))
data.update(optional_to_form(self.right, "marginRight"))
return data


@enum.unique
class EmulatedMediaType(str, enum.Enum):
Print = enum.auto()
Screen = enum.auto()

def to_form(self) -> Dict[str, str]:
if self.value == EmulatedMediaType.Print.value:
return {"emulatedMediaType": "print"}
elif self.value == EmulatedMediaType.Screen.value:
return {"emulatedMediaType": "screen"}
else: # pragma: no cover
raise NotImplementedError(self.value)
22 changes: 0 additions & 22 deletions src/gotenberg_client/pdf_format.py

This file was deleted.

14 changes: 7 additions & 7 deletions tests/test_convert_chromium_html.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
from gotenberg_client.client import GotenbergClient
from gotenberg_client.convert.chromium import A4
from gotenberg_client.convert.chromium import Margin
from gotenberg_client.convert.common import PageOrientationOptions
from gotenberg_client.pdf_format import PdfAFormatOptions
from gotenberg_client.options import PageOrientation
from gotenberg_client.options import PdfAFormat
from tests.conftest import SAMPLE_DIR
from tests.conftest import SAVE_DIR
from tests.conftest import SAVE_OUTPUTS
Expand Down Expand Up @@ -60,9 +60,9 @@ def test_convert_additional_files(self, client: GotenbergClient):

@pytest.mark.parametrize(
("gt_format", "pike_format"),
[(PdfAFormatOptions.A1a, "1A"), (PdfAFormatOptions.A2b, "2B"), (PdfAFormatOptions.A3b, "3B")],
[(PdfAFormat.A1a, "1A"), (PdfAFormat.A2b, "2B"), (PdfAFormat.A3b, "3B")],
)
def test_convert_pdfa_1a_format(self, client: GotenbergClient, gt_format: PdfAFormatOptions, pike_format: str):
def test_convert_pdfa_1a_format(self, client: GotenbergClient, gt_format: PdfAFormat, pike_format: str):
test_file = SAMPLE_DIR / "basic.html"

with client.chromium.html_to_pdf() as route:
Expand Down Expand Up @@ -117,13 +117,13 @@ def test_convert_render_control(self, client: GotenbergClient, httpx_mock: HTTPX

@pytest.mark.parametrize(
("orientation"),
[PageOrientationOptions.Landscape, PageOrientationOptions.Potrait],
[PageOrientation.Landscape, PageOrientation.Potrait],
)
def test_convert_orientation(
self,
client: GotenbergClient,
httpx_mock: HTTPXMock,
orientation: PageOrientationOptions,
orientation: PageOrientation,
):
httpx_mock.add_response(method="POST")
test_file = SAMPLE_DIR / "basic.html"
Expand All @@ -134,6 +134,6 @@ def test_convert_orientation(
request = httpx_mock.get_request()
verify_stream_contains(
"landscape",
"true" if orientation == PageOrientationOptions.Landscape else "false",
"true" if orientation == PageOrientation.Landscape else "false",
request.stream,
)
8 changes: 4 additions & 4 deletions tests/test_convert_chromium_url.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from pytest_httpx import HTTPXMock

from gotenberg_client.client import GotenbergClient
from gotenberg_client.convert.chromium import EmulatedMediaTypeChoices
from gotenberg_client.convert.chromium import EmulatedMediaType
from tests.utils import verify_stream_contains


Expand All @@ -20,13 +20,13 @@ def test_basic_convert(self, client: GotenbergClient):

@pytest.mark.parametrize(
("emulation"),
[EmulatedMediaTypeChoices.Screen, EmulatedMediaTypeChoices.Print],
[EmulatedMediaType.Screen, EmulatedMediaType.Print],
)
def test_convert_orientation(
self,
client: GotenbergClient,
httpx_mock: HTTPXMock,
emulation: EmulatedMediaTypeChoices,
emulation: EmulatedMediaType,
):
httpx_mock.add_response(method="POST")

Expand All @@ -36,7 +36,7 @@ def test_convert_orientation(
request = httpx_mock.get_request()
verify_stream_contains(
"emulatedMediaType",
"screen" if emulation == EmulatedMediaTypeChoices.Screen else "print",
"screen" if emulation == EmulatedMediaType.Screen else "print",
request.stream,
)

Expand Down
6 changes: 3 additions & 3 deletions tests/test_convert_libre_office.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

from gotenberg_client.base import guess_mime_type_stdlib
from gotenberg_client.client import GotenbergClient
from gotenberg_client.pdf_format import PdfAFormatOptions
from gotenberg_client.options import PdfAFormat
from tests.conftest import SAMPLE_DIR
from tests.conftest import SAVE_DIR
from tests.conftest import SAVE_OUTPUTS
Expand Down Expand Up @@ -100,12 +100,12 @@ def test_libre_office_convert_std_lib_mime(self, client: GotenbergClient):

@pytest.mark.parametrize(
("gt_format", "pike_format"),
[(PdfAFormatOptions.A1a, "1A"), (PdfAFormatOptions.A2b, "2B"), (PdfAFormatOptions.A3b, "3B")],
[(PdfAFormat.A1a, "1A"), (PdfAFormat.A2b, "2B"), (PdfAFormat.A3b, "3B")],
)
def test_libre_office_convert_xlsx_format_pdfa(
self,
client: GotenbergClient,
gt_format: PdfAFormatOptions,
gt_format: PdfAFormat,
pike_format: str,
):
test_file = SAMPLE_DIR / "sample.xlsx"
Expand Down
Loading

0 comments on commit d3684ab

Please sign in to comment.