Skip to content

Commit db922d9

Browse files
Migrate to uv and update python version support (#180)
* Migrate to uv and update python version support * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent a80ee86 commit db922d9

File tree

11 files changed

+1450
-73
lines changed

11 files changed

+1450
-73
lines changed

.github/dependabot.yml

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,16 @@
11
version: 2
22
updates:
3-
- package-ecosystem: pip
3+
- package-ecosystem: uv
44
directory: "/"
55
schedule:
6-
interval: daily
7-
open-pull-requests-limit: 10
6+
interval: monthly
7+
groups:
8+
all-dependencies:
9+
patterns: ["*"]
10+
- package-ecosystem: "github-actions"
11+
directory: "/"
12+
schedule:
13+
interval: "monthly"
14+
groups:
15+
all-actions:
16+
patterns: ["*"]

.github/workflows/build-release.yml

Lines changed: 43 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -15,45 +15,57 @@ jobs:
1515
fail-fast: false
1616
matrix:
1717
include:
18-
- { name: "3.8", python: "3.8", tox: py38 }
19-
- { name: "lowest", python: "3.8", tox: py38-lowest }
20-
- { name: "3.12-apispecdev", python: "3.12", tox: py312-apispecdev }
18+
- { name: "3.10", tox: py310 }
19+
- { name: "3.14", tox: py314 }
20+
- { name: "lowest", tox: py310-lowest }
21+
- { name: "3.14-apispecdev", tox: py314-apispecdev }
2122
steps:
22-
- uses: actions/checkout@v3.1.0
23-
- uses: actions/setup-python@v4.3.0
23+
- uses: actions/checkout@v6
24+
- uses: astral-sh/setup-uv@v7
2425
with:
25-
python-version: ${{ matrix.python }}
26-
- run: python -m pip install --upgrade pip
27-
- run: python -m pip install tox
28-
- run: python -m tox -e ${{ matrix.tox }}
29-
26+
enable-cache: true
27+
- run: uv run tox -e ${{ matrix.tox }}
28+
build:
29+
name: Build package
30+
runs-on: ubuntu-latest
31+
steps:
32+
- uses: actions/checkout@v6
33+
- uses: astral-sh/setup-uv@v7
34+
with:
35+
enable-cache: true
36+
- run: uv build
37+
- run: uvx twine check --strict dist/*
38+
- name: Store the distribution packages
39+
uses: actions/upload-artifact@v7
40+
with:
41+
name: python-package-distributions
42+
path: dist/
43+
# this duplicates pre-commit.ci, so only run it on tags
44+
# it guarantees that linting is passing prior to a release
3045
lint-pre-release:
31-
name: lint
3246
if: startsWith(github.ref, 'refs/tags')
3347
runs-on: ubuntu-latest
3448
steps:
35-
- uses: actions/checkout@v3.1.0
36-
- uses: actions/setup-python@v4.3.0
49+
- uses: actions/checkout@v6
50+
- uses: astral-sh/setup-uv@v7
3751
with:
38-
python-version: "3.11"
39-
- run: python -m pip install --upgrade pip
40-
- run: python -m pip install tox
41-
- run: python -m tox -e lint
42-
release:
43-
needs: [tests, lint-pre-release]
52+
enable-cache: true
53+
- run: uv run tox -e lint
54+
publish-to-pypi:
4455
name: PyPI release
45-
if: startsWith(github.ref, 'refs/tags')
56+
if: startsWith(github.ref, 'refs/tags/')
57+
needs: [build, tests, lint-pre-release]
4658
runs-on: ubuntu-latest
59+
environment:
60+
name: pypi
61+
url: https://pypi.org/p/apispec-webframeworks
62+
permissions:
63+
id-token: write
4764
steps:
48-
- uses: actions/checkout@v3.1.0
49-
- uses: actions/setup-python@v4.3.0
65+
- name: Download all the dists
66+
uses: actions/download-artifact@v7
5067
with:
51-
python-version: "3.11"
52-
- name: install requirements
53-
run: python -m pip install build twine
54-
- name: build dists
55-
run: python -m build
56-
- name: check package metadata
57-
run: twine check dist/*
58-
- name: publish
59-
run: twine upload -u __token__ -p ${{ secrets.PYPI_API_TOKEN }} dist/*
68+
name: python-package-distributions
69+
path: dist/
70+
- name: Publish distribution to PyPI
71+
uses: pypa/gh-action-pypi-publish@release/v1

.pre-commit-config.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,7 @@ repos:
2222
- id: mypy
2323
files: ^src/apispec_webframeworks/
2424
additional_dependencies: ["Flask==2.3.3", "tornado>=6", "bottle", "apispec[yaml]>=5.2.1", types-setuptools]
25+
- repo: https://github.com/astral-sh/uv-pre-commit
26+
rev: 0.10.9
27+
hooks:
28+
- id: uv-lock

CHANGELOG.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
Changelog
22
---------
33

4+
unreleased
5+
++++++++++
6+
7+
Other:
8+
9+
* Support Python 3.10-3.14. Older versions are no longer supported.
10+
411
1.2.0 (2024-09-16)
512
++++++++++++++++++
613

pyproject.toml

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,36 +3,38 @@ name = "apispec-webframeworks"
33
version = "1.2.0"
44
description = "Web framework plugins for apispec."
55
readme = "README.rst"
6-
license = { file = "LICENSE" }
7-
maintainers = [{ name = "Steven Loria", email = "sloria1@gmail.com" }]
6+
license = "MIT"
7+
maintainers = [{ name = "Steven Loria", email = "oss@stevenloria.com" }]
88
classifiers = [
99
"Intended Audience :: Developers",
10-
"License :: OSI Approved :: MIT License",
1110
"Natural Language :: English",
1211
"Programming Language :: Python :: 3",
13-
"Programming Language :: Python :: 3.8",
14-
"Programming Language :: Python :: 3.9",
1512
"Programming Language :: Python :: 3.10",
1613
"Programming Language :: Python :: 3.11",
1714
"Programming Language :: Python :: 3.12",
15+
"Programming Language :: Python :: 3.13",
16+
"Programming Language :: Python :: 3.14",
1817
]
19-
requires-python = ">=3.8"
18+
requires-python = ">=3.10"
2019
dependencies = ["apispec[yaml]>=6.0.0"]
2120

2221
[project.urls]
2322
Funding = "https://opencollective.com/marshmallow"
2423
Issues = "https://github.com/marshmallow-code/apispec-webframeworks/issues"
2524
Source = "https://github.com/marshmallow-code/apispec-webframeworks"
2625

27-
[project.optional-dependencies]
26+
[dependency-groups]
2827
tests = [
2928
"pytest",
3029
"Flask>=2.3.3",
3130
"tornado>=6",
3231
"bottle>=0.12.25",
3332
"aiohttp>=3.9.3",
3433
]
35-
dev = ["apispec-webframeworks[tests]", "tox", "pre-commit>=3.5,<5.0"]
34+
dev = [{ include-group = "tests" }, "tox", "tox-uv", "pre-commit>=3.5,<5.0"]
35+
36+
[tool.uv]
37+
default-groups = ["dev"]
3638

3739
[build-system]
3840
requires = ["flit_core<4"]

src/apispec_webframeworks/aiohttp.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ async def hello(request):
4343
4444
""" # noqa: E501
4545

46-
from typing import Any, List, Optional
46+
from typing import Any
4747

4848
from aiohttp.web import AbstractRoute
4949
from apispec import BasePlugin, yaml_utils
@@ -52,13 +52,13 @@ async def hello(request):
5252
class AiohttpPlugin(BasePlugin):
5353
def path_helper(
5454
self,
55-
path: Optional[str] = None,
56-
operations: Optional[dict] = None,
57-
parameters: Optional[List[dict]] = None,
55+
path: str | None = None,
56+
operations: dict | None = None,
57+
parameters: list[dict] | None = None,
5858
*,
59-
route: Optional[AbstractRoute] = None,
59+
route: AbstractRoute | None = None,
6060
**kwargs: Any,
61-
) -> Optional[str]:
61+
) -> str | None:
6262
"""Path helper that allows passing a aiohttp AbstractRoute"""
6363
assert operations is not None
6464
assert route is not None

src/apispec_webframeworks/bottle.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ def gist_detail(gist_id):
2626
""" # noqa: E501
2727

2828
import re
29-
from typing import Any, Callable, List, Optional
29+
from collections.abc import Callable
30+
from typing import Any
3031

3132
from apispec import BasePlugin, yaml_utils
3233
from apispec.exceptions import APISpecError
@@ -58,13 +59,13 @@ def _route_for_view(app: Bottle, view: Callable[..., Any]) -> Route:
5859

5960
def path_helper(
6061
self,
61-
path: Optional[str] = None,
62-
operations: Optional[dict] = None,
63-
parameters: Optional[List[dict]] = None,
62+
path: str | None = None,
63+
operations: dict | None = None,
64+
parameters: list[dict] | None = None,
6465
*,
65-
view: Optional[Any] = None,
66+
view: Any | None = None,
6667
**kwargs: Any,
67-
) -> Optional[str]:
68+
) -> str | None:
6869
"""Path helper that allows passing a bottle view function."""
6970
assert operations is not None
7071
assert view is not None

src/apispec_webframeworks/flask.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@ def post(self):
7373
""" # noqa: E501
7474

7575
import re
76-
from typing import TYPE_CHECKING, Any, Callable, List, Optional, Union
76+
from collections.abc import Callable
77+
from typing import TYPE_CHECKING, Any, Union
7778

7879
from apispec import BasePlugin, yaml_utils
7980
from apispec.exceptions import APISpecError
@@ -103,7 +104,7 @@ def flaskpath2openapi(path: str) -> str:
103104
@staticmethod
104105
def _rule_for_view(
105106
view: Union[Callable[..., Any], "RouteCallable"],
106-
app: Optional[Flask] = None,
107+
app: Flask | None = None,
107108
) -> Rule:
108109
if app is None:
109110
app = current_app
@@ -122,14 +123,14 @@ def _rule_for_view(
122123

123124
def path_helper(
124125
self,
125-
path: Optional[str] = None,
126-
operations: Optional[dict] = None,
127-
parameters: Optional[List[dict]] = None,
126+
path: str | None = None,
127+
operations: dict | None = None,
128+
parameters: list[dict] | None = None,
128129
*,
129-
view: Optional[Union[Callable[..., Any], "RouteCallable"]] = None,
130-
app: Optional[Flask] = None,
130+
view: Union[Callable[..., Any], "RouteCallable"] | None = None,
131+
app: Flask | None = None,
131132
**kwargs: Any,
132-
) -> Optional[str]:
133+
) -> str | None:
133134
"""Path helper that allows passing a Flask view function."""
134135
assert view is not None
135136
assert operations is not None

src/apispec_webframeworks/tornado.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ def get(self):
3232
""" # noqa: E501
3333

3434
import inspect
35-
from typing import Any, Callable, Dict, Iterator, List, Optional, Union, cast
35+
from collections.abc import Callable, Iterator
36+
from typing import Any, cast
3637

3738
from apispec import BasePlugin, yaml_utils
3839
from apispec.exceptions import APISpecError
@@ -46,7 +47,7 @@ class TornadoPlugin(BasePlugin):
4647
@staticmethod
4748
def _operations_from_methods(
4849
handler_class: RequestHandler,
49-
) -> Iterator[Dict[str, dict]]:
50+
) -> Iterator[dict[str, dict]]:
5051
"""Generator of operations described in handler's http methods
5152
5253
:param handler_class:
@@ -103,13 +104,13 @@ def _extensions_from_handler(handler_class: RequestHandler) -> dict:
103104

104105
def path_helper(
105106
self,
106-
path: Optional[str] = None,
107-
operations: Optional[dict] = None,
108-
parameters: Optional[List[dict]] = None,
107+
path: str | None = None,
108+
operations: dict | None = None,
109+
parameters: list[dict] | None = None,
109110
*,
110-
urlspec: Optional[Union[URLSpec, tuple]] = None,
111+
urlspec: URLSpec | tuple | None = None,
111112
**kwargs: Any,
112-
) -> Optional[str]:
113+
) -> str | None:
113114
"""Path helper that allows passing a Tornado URLSpec or tuple."""
114115
assert operations is not None
115116
assert urlspec is not None

tox.ini

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
[tox]
22
envlist=
33
lint
4-
py{38,39,310,311,312}
5-
py312-apispecdev
6-
py38-lowest
4+
py{310,311,312,313,314}
5+
py314-apispecdev
6+
py310-lowest
77

88
[testenv]
9-
extras = tests
9+
dependency_groups = tests
1010
deps =
1111
apispecdev: https://github.com/marshmallow-code/apispec/archive/dev.tar.gz
1212
lowest: aiohttp==3.9.3

0 commit comments

Comments
 (0)