Skip to content

Commit

Permalink
Breaking: Drop support for Python 3.8 (#43)
Browse files Browse the repository at this point in the history
  • Loading branch information
stumpylog authored Dec 10, 2024
1 parent 50206a1 commit 0b910c0
Show file tree
Hide file tree
Showing 18 changed files with 76 additions and 113 deletions.
3 changes: 1 addition & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,7 @@ jobs:
strategy:
fail-fast: false
matrix:
# No pikepdf wheels for pypy3.8
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13', 'pypy3.9', 'pypy3.10']
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13', 'pypy3.9', 'pypy3.10']

steps:
-
Expand Down
6 changes: 3 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ repos:
- id: detect-private-key
# See https://github.com/prettier/prettier/issues/15742 for the fork reason
- repo: https://github.com/rbubley/mirrors-prettier
rev: "v3.3.3"
rev: "v3.4.2"
hooks:
- id: prettier
types_or:
Expand All @@ -45,13 +45,13 @@ repos:
- id: codespell
# Python hooks
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: 'v0.6.9'
rev: 'v0.8.2'
hooks:
# Run the linter.
- id: ruff
# Run the formatter.
- id: ruff-format
- repo: https://github.com/tox-dev/pyproject-fmt
rev: "2.2.4"
rev: "v2.5.0"
hooks:
- id: pyproject-fmt
10 changes: 7 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Breaking Change

- Dopped support for Python 3.8 ([#43](https://github.com/stumpylog/gotenberg-client/pull/43))

### Added

- Official support and testing for Python 3.13 ([#25](https://github.com/stumpylog/tika-client/pull/25))
- Support for setting PDF metadata ([#42](https://github.com/stumpylog/tika-client/pull/42))
- Initial work by @spechtx in ([#40](https://github.com/stumpylog/tika-client/pull/40))
- Official support and testing for Python 3.13 ([#25](https://github.com/stumpylog/gotenberg-client/pull/25))
- Support for setting PDF metadata ([#42](https://github.com/stumpylog/gotenberg-client/pull/42))
- Initial work by @spechtx in ([#40](https://github.com/stumpylog/gotenberg-client/pull/40))

### Changed

Expand Down
18 changes: 7 additions & 11 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ license = "MPL-2.0"
authors = [
{ name = "Trenton H", email = "[email protected]" },
]
requires-python = ">=3.8"
requires-python = ">=3.9"
classifiers = [
"Development Status :: 4 - Beta",
"Environment :: Web Environment",
Expand All @@ -25,7 +25,6 @@ classifiers = [
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
Expand All @@ -36,8 +35,7 @@ classifiers = [
]
dynamic = [ "version" ]
dependencies = [
"httpx[http2]~=0.24; python_version<'3.9'",
"httpx[http2]~=0.27; python_version>='3.9'",
"httpx[http2]~=0.28",
"typing-extensions; python_version<'3.11'",
]

Expand Down Expand Up @@ -75,7 +73,6 @@ randomize = true
dependencies = [
"coverage-enable-subprocess == 1.0",
"coverage[toml] ~= 7.6",
"pytest < 8.0; python_version < '3.9'",
"pytest ~= 8.3; python_version >= '3.9'",
"pytest-mock ~= 3.14",
"pytest-randomly ~= 3.15",
Expand All @@ -84,8 +81,7 @@ dependencies = [
]
extra-dependencies = [
"pytest-sugar",
"pytest-httpx == 0.30.0; python_version >= '3.9'",
"pytest-httpx ~= 0.22; python_version < '3.9'",
"pytest-httpx ~= 0.35",
"pikepdf",
"python-magic",
"pytest-docker ~= 3.1",
Expand All @@ -111,19 +107,19 @@ cov-report = [
]

[[tool.hatch.envs.hatch-test.matrix]]
python = [ "3.8", "3.9", "3.10", "3.11", "3.12", "3.13", "pypy3.9", "pypy3.10" ]
python = [ "3.9", "3.10", "3.11", "3.12", "3.13", "pypy3.9", "pypy3.10" ]

#
# Custom Environments
#
[tool.hatch.envs.typing]
detached = true
dependencies = [
"mypy ~= 1.11",
"mypy ~= 1.13",
"httpx",
"pytest",
"pikepdf",
"pytest-httpx == 0.30.0",
"pytest-httpx ~= 0.35",
]

[tool.hatch.envs.typing.scripts]
Expand Down Expand Up @@ -170,7 +166,7 @@ deploy = [
#

[tool.ruff]
target-version = "py38"
target-version = "py39"
line-length = 120

# https://docs.astral.sh/ruff/settings/
Expand Down
13 changes: 5 additions & 8 deletions src/gotenberg_client/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,7 @@
from pathlib import Path
from time import sleep
from types import TracebackType
from typing import Dict
from typing import Optional
from typing import Tuple
from typing import Type

from httpx import Client
from httpx import HTTPStatusError
Expand Down Expand Up @@ -71,21 +68,21 @@ def __init__(self, client: Client, api_route: str) -> None:
self._route = api_route
self._stack = ExitStack()
# These are the options that will be set to Gotenberg. Things like PDF/A
self._form_data: Dict[str, str] = {}
self._form_data: dict[str, str] = {}
# These are the names of files, mapping to their Path
self._file_map: Dict[str, Path] = {}
self._file_map: dict[str, Path] = {}
# Additional in memory resources, mapping the referenced name to the content and an optional mimetype
self._in_memory_resources: Dict[str, Tuple[str, Optional[str]]] = {}
self._in_memory_resources: dict[str, tuple[str, Optional[str]]] = {}
# Any header that will also be sent
self._headers: Dict[str, str] = {}
self._headers: dict[str, str] = {}

def __enter__(self) -> Self:
self.reset()
return self

def __exit__(
self,
exc_type: Optional[Type[BaseException]],
exc_type: Optional[type[BaseException]],
exc_val: Optional[BaseException],
exc_tb: Optional[TracebackType],
) -> None:
Expand Down
8 changes: 3 additions & 5 deletions src/gotenberg_client/_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@
# SPDX-License-Identifier: MPL-2.0
import logging
from types import TracebackType
from typing import Dict
from typing import Optional
from typing import Type

from httpx import Client

Expand Down Expand Up @@ -65,7 +63,7 @@ def __init__(
self.merge = MergeApi(self._client)
self.health = HealthCheckApi(self._client)

def add_headers(self, header: Dict[str, str]) -> None:
def add_headers(self, header: dict[str, str]) -> None:
"""
Update the httpx Client headers with the given values.
Expand Down Expand Up @@ -110,7 +108,7 @@ def set_error_webhook_http_method(self, method: HttpMethodsType = "PUT") -> None
"""
self.add_headers({"Gotenberg-Webhook-Error-Method": method})

def set_webhook_extra_headers(self, extra_headers: Dict[str, str]) -> None:
def set_webhook_extra_headers(self, extra_headers: dict[str, str]) -> None:
"""
Set additional HTTP headers for Gotenberg to use when calling webhooks.
Expand Down Expand Up @@ -138,7 +136,7 @@ def close(self) -> None:

def __exit__(
self,
exc_type: Optional[Type[BaseException]],
exc_type: Optional[type[BaseException]],
exc_val: Optional[BaseException],
exc_tb: Optional[TracebackType],
) -> None:
Expand Down
8 changes: 3 additions & 5 deletions src/gotenberg_client/_convert/chromium.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@
# SPDX-License-Identifier: MPL-2.0
import logging
from pathlib import Path
from typing import List
from typing import Literal
from typing import Optional
from typing import Tuple

from httpx import Client

Expand Down Expand Up @@ -83,7 +81,7 @@ def string_resource(self, resource: str, name: str, mime_type: Optional[str] = N
self._add_in_memory_file(resource, name=name, mime_type=mime_type)
return self

def resources(self, resources: List[Path]) -> Self:
def resources(self, resources: list[Path]) -> Self:
"""
Adds multiple resource files for the index HTML file to reference.
Expand All @@ -95,7 +93,7 @@ def resources(self, resources: List[Path]) -> Self:

def string_resources(
self,
resources: List[Tuple[str, str, Optional[str]]],
resources: list[tuple[str, str, Optional[str]]],
) -> Self:
"""
Process string resources.
Expand Down Expand Up @@ -215,7 +213,7 @@ def markdown_file(self, markdown_file: Path) -> Self:

return self

def markdown_files(self, markdown_files: List[Path]) -> Self:
def markdown_files(self, markdown_files: list[Path]) -> Self:
"""
Adds multiple Markdown files to be converted.
Expand Down
12 changes: 5 additions & 7 deletions src/gotenberg_client/_convert/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,10 @@
# SPDX-License-Identifier: MPL-2.0
import json
import logging
from collections.abc import Iterable
from datetime import datetime
from pathlib import Path
from typing import Dict
from typing import Final
from typing import Iterable
from typing import List
from typing import Optional
from typing import Union
from warnings import warn
Expand Down Expand Up @@ -195,7 +193,7 @@ def user_agent(self, agent: str) -> Self:
self._form_data.update({"userAgent": agent}) # type: ignore[attr-defined,misc]
return self

def headers(self, headers: Dict[str, str]) -> Self:
def headers(self, headers: dict[str, str]) -> Self:
json_str = json.dumps(headers)
self._form_data.update({"extraHttpHeaders": json_str}) # type: ignore[attr-defined,misc]
return self
Expand Down Expand Up @@ -294,7 +292,7 @@ def metadata(
pdf_copyright: Optional[str] = None,
creation_date: Optional[datetime] = None,
creator: Optional[str] = None,
keywords: Optional[List[str]] = None,
keywords: Optional[list[str]] = None,
marked: Optional[bool] = None,
modification_date: Optional[datetime] = None,
pdf_version: Optional[float] = None,
Expand Down Expand Up @@ -344,12 +342,12 @@ def metadata(
raise InvalidKeywordError("Keywords cannot contain commas") # noqa: EM101, TRY003

# Get existing metadata if any
existing_metadata: Dict[str, Union[str, bool, float]] = {}
existing_metadata: dict[str, Union[str, bool, float]] = {}
if "metadata" in self._form_data: # type: ignore[attr-defined,misc]
existing_metadata = json.loads(self._form_data["metadata"]) # type: ignore[attr-defined,misc]

# Convert validated metadata to dictionary
metadata: Dict[str, Union[str, bool, float]] = {}
metadata: dict[str, Union[str, bool, float]] = {}

if author:
metadata["Author"] = author
Expand Down
3 changes: 1 addition & 2 deletions src/gotenberg_client/_convert/libre_office.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
#
# SPDX-License-Identifier: MPL-2.0
from pathlib import Path
from typing import List
from typing import Union

from httpx import Client
Expand Down Expand Up @@ -54,7 +53,7 @@ def convert(self, input_file_path: Path) -> Self:
self._result_is_zip = True
return self

def convert_files(self, file_paths: List[Path]) -> Self:
def convert_files(self, file_paths: list[Path]) -> Self:
"""
Adds all provided files for conversion to individual PDFs.
Expand Down
3 changes: 1 addition & 2 deletions src/gotenberg_client/_convert/pdfa.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
#
# SPDX-License-Identifier: MPL-2.0
from pathlib import Path
from typing import List

from gotenberg_client._base import BaseApi
from gotenberg_client._base import BaseSingleFileResponseRoute
Expand Down Expand Up @@ -35,7 +34,7 @@ def convert(self, file_path: Path) -> Self:
self._add_file_map(file_path)
return self

def convert_files(self, file_paths: List[Path]) -> Self:
def convert_files(self, file_paths: list[Path]) -> Self:
"""
Converts multiple PDF files to the provided PDF/A format.
Expand Down
3 changes: 1 addition & 2 deletions src/gotenberg_client/_merge.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
# SPDX-License-Identifier: MPL-2.0
from pathlib import Path
from typing import Final
from typing import List

from httpx import Client

Expand Down Expand Up @@ -38,7 +37,7 @@ def __init__(self, client: Client, api_route: str) -> None:
super().__init__(client, api_route)
self._next = 1

def merge(self, files: List[Path]) -> Self:
def merge(self, files: list[Path]) -> Self:
"""
Add the given files to the merge operation.
Expand Down
5 changes: 2 additions & 3 deletions src/gotenberg_client/_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
# SPDX-License-Identifier: MPL-2.0
from importlib.util import find_spec
from pathlib import Path
from typing import Dict
from typing import Final
from typing import Optional
from typing import Union
Expand All @@ -12,12 +11,12 @@


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


def optional_to_form(value: Optional[FormFieldType], name: str) -> Dict[str, str]:
def optional_to_form(value: Optional[FormFieldType], name: str) -> dict[str, str]:
"""
Converts an optional value to a form data field with the given name,
handling None values gracefully.
Expand Down
Loading

0 comments on commit 0b910c0

Please sign in to comment.