This is an automated email from the ASF dual-hosted git repository.
sbp pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tooling-trusted-releases.git
The following commit(s) were added to refs/heads/main by this push:
new 831e2ef Use consistent response types throughout
831e2ef is described below
commit 831e2efcbc2354fd2a50b84383a4b8ea9019dec6
Author: Sean B. Palmer <[email protected]>
AuthorDate: Tue Nov 4 15:33:21 2025 +0000
Use consistent response types throughout
---
atr/admin/__init__.py | 63 ++++++++++++++++++++++++------------------------
atr/api/__init__.py | 2 +-
atr/get/announce.py | 3 +--
atr/get/candidate.py | 5 ++--
atr/get/compose.py | 3 +--
atr/get/download.py | 27 ++++++---------------
atr/get/draft.py | 6 +----
atr/get/file.py | 3 +--
atr/get/finish.py | 5 +---
atr/get/ignores.py | 3 +--
atr/get/keys.py | 5 ++--
atr/get/preview.py | 5 ++--
atr/get/projects.py | 9 ++-----
atr/get/published.py | 8 +++---
atr/get/ref.py | 3 +--
atr/get/release.py | 5 ++--
atr/get/root.py | 3 +--
atr/get/start.py | 4 +--
atr/get/tokens.py | 4 +--
atr/get/upload.py | 4 +--
atr/get/vote.py | 3 +--
atr/get/voting.py | 4 +--
atr/post/announce.py | 7 +-----
atr/post/candidate.py | 4 +--
atr/post/distribution.py | 7 +-----
atr/post/draft.py | 18 ++++++--------
atr/post/finish.py | 7 ++----
atr/post/ignores.py | 7 +++---
atr/post/keys.py | 13 +++++-----
atr/post/preview.py | 7 ++----
atr/post/projects.py | 11 +++------
atr/post/resolve.py | 7 +++---
atr/post/revisions.py | 3 +--
atr/post/sbom.py | 8 ++----
atr/post/start.py | 4 +--
atr/post/tokens.py | 7 ++----
atr/post/upload.py | 4 +--
atr/post/user.py | 3 +--
atr/post/vote.py | 3 +--
atr/post/voting.py | 4 +--
atr/shared/__init__.py | 3 +--
atr/shared/finish.py | 22 ++++++++---------
atr/shared/keys.py | 5 ++--
atr/shared/projects.py | 11 +++------
atr/shared/start.py | 3 +--
atr/shared/tokens.py | 11 ++++-----
atr/shared/upload.py | 3 +--
atr/shared/voting.py | 7 +++---
atr/web.py | 8 ++++--
49 files changed, 141 insertions(+), 233 deletions(-)
diff --git a/atr/admin/__init__.py b/atr/admin/__init__.py
index 003cd98..1be3b6c 100644
--- a/atr/admin/__init__.py
+++ b/atr/admin/__init__.py
@@ -32,7 +32,6 @@ import asfquart.base as base
import asfquart.session
import quart
import sqlalchemy.orm as orm
-import werkzeug.wrappers.response as response
import atr.blueprints.admin as admin
import atr.config as config
@@ -114,16 +113,16 @@ async def all_releases(session: web.Committer) -> str:
@admin.get("/browse-as")
-async def browse_as_get(session: web.Committer) -> str | response.Response:
+async def browse_as_get(session: web.Committer) -> str | web.WerkzeugResponse:
return await _browse_as(session)
@admin.post("/browse-as")
-async def browse_as_post(session: web.Committer) -> str | response.Response:
+async def browse_as_post(session: web.Committer) -> str | web.WerkzeugResponse:
return await _browse_as(session)
-async def _browse_as(session: web.Committer) -> str | response.Response:
+async def _browse_as(session: web.Committer) -> str | web.WerkzeugResponse:
"""Allows an admin to browse as another user."""
# TODO: Enable this in debugging mode only?
import atr.get.root as root
@@ -172,7 +171,7 @@ async def _browse_as(session: web.Committer) -> str |
response.Response:
@admin.get("/configuration")
-async def configuration(session: web.Committer) ->
quart.wrappers.response.Response:
+async def configuration(session: web.Committer) -> web.QuartResponse:
"""Display the current application configuration values."""
conf = config.get()
@@ -299,7 +298,7 @@ async def _data(session: web.Committer, model: str =
"Committee") -> str:
@admin.get("/delete-test-openpgp-keys")
-async def delete_test_openpgp_keys_get(session: web.Committer) ->
quart.Response | response.Response:
+async def delete_test_openpgp_keys_get(session: web.Committer) -> web.Response:
if not config.get().ALLOW_TESTS:
raise base.ASFQuartException("Test operations are disabled in this
environment", errorcode=403)
@@ -309,7 +308,7 @@ async def delete_test_openpgp_keys_get(session:
web.Committer) -> quart.Response
@admin.post("/delete-test-openpgp-keys")
-async def delete_test_openpgp_keys_post(session: web.Committer) ->
quart.Response | response.Response:
+async def delete_test_openpgp_keys_post(session: web.Committer) ->
web.Response:
"""Delete all test user OpenPGP keys and their links."""
if not config.get().ALLOW_TESTS:
raise base.ASFQuartException("Test operations are disabled in this
environment", errorcode=403)
@@ -328,16 +327,16 @@ async def delete_test_openpgp_keys_post(session:
web.Committer) -> quart.Respons
@admin.get("/delete-committee-keys")
-async def delete_committee_keys_get(session: web.Committer) -> str |
response.Response:
+async def delete_committee_keys_get(session: web.Committer) -> str |
web.WerkzeugResponse:
return await _delete_committee_keys(session)
@admin.post("/delete-committee-keys")
-async def delete_committee_keys_post(session: web.Committer) -> str |
response.Response:
+async def delete_committee_keys_post(session: web.Committer) -> str |
web.WerkzeugResponse:
return await _delete_committee_keys(session)
-async def _delete_committee_keys(session: web.Committer) -> str |
response.Response:
+async def _delete_committee_keys(session: web.Committer) -> str |
web.WerkzeugResponse:
form = await DeleteCommitteeKeysForm.create_form()
async with db.session() as data:
all_committees = await
data.committee(_public_signing_keys=True).order_by(sql.Committee.name).all()
@@ -389,16 +388,16 @@ async def _delete_committee_keys(session: web.Committer)
-> str | response.Respo
@admin.get("/delete-release")
-async def delete_release_get(session: web.Committer) -> str |
response.Response:
+async def delete_release_get(session: web.Committer) -> str |
web.WerkzeugResponse:
return await _delete_release(session)
@admin.post("/delete-release")
-async def delete_release_post(session: web.Committer) -> str |
response.Response:
+async def delete_release_post(session: web.Committer) -> str |
web.WerkzeugResponse:
return await _delete_release(session)
-async def _delete_release(session: web.Committer) -> str | response.Response:
+async def _delete_release(session: web.Committer) -> str |
web.WerkzeugResponse:
"""Page to delete selected releases and their associated data and files."""
form = await DeleteReleaseForm.create_form()
@@ -428,7 +427,7 @@ async def _delete_release(session: web.Committer) -> str |
response.Response:
@admin.get("/env")
-async def env(session: web.Committer) -> quart.wrappers.response.Response:
+async def env(session: web.Committer) -> web.QuartResponse:
"""Display the environment variables."""
env_vars = []
for key, value in os.environ.items():
@@ -437,16 +436,16 @@ async def env(session: web.Committer) ->
quart.wrappers.response.Response:
@admin.get("/keys/check")
-async def keys_check_get(session: web.Committer) -> quart.Response:
+async def keys_check_get(session: web.Committer) -> web.QuartResponse:
return await _keys_check(session)
@admin.post("/keys/check")
-async def keys_check_post(session: web.Committer) -> quart.Response:
+async def keys_check_post(session: web.Committer) -> web.QuartResponse:
return await _keys_check(session)
-async def _keys_check(session: web.Committer) -> quart.Response:
+async def _keys_check(session: web.Committer) -> web.QuartResponse:
"""Check public signing key details."""
if quart.request.method != "POST":
check_form = await CheckKeysForm.create_form()
@@ -462,16 +461,16 @@ async def _keys_check(session: web.Committer) ->
quart.Response:
@admin.get("/keys/regenerate-all")
-async def keys_regenerate_all_get(session: web.Committer) -> quart.Response:
+async def keys_regenerate_all_get(session: web.Committer) -> web.QuartResponse:
return await _keys_regenerate_all(session)
@admin.post("/keys/regenerate-all")
-async def keys_regenerate_all_post(session: web.Committer) -> quart.Response:
+async def keys_regenerate_all_post(session: web.Committer) ->
web.QuartResponse:
return await _keys_regenerate_all(session)
-async def _keys_regenerate_all(session: web.Committer) -> quart.Response:
+async def _keys_regenerate_all(session: web.Committer) -> web.QuartResponse:
"""Regenerate the KEYS file for all committees."""
if quart.request.method != "POST":
regenerate_form = await RegenerateKeysForm.create_form()
@@ -500,16 +499,16 @@ async def _keys_regenerate_all(session: web.Committer) ->
quart.Response:
@admin.get("/keys/update")
-async def keys_update_get(session: web.Committer) -> str | response.Response |
tuple[Mapping[str, Any], int]:
+async def keys_update_get(session: web.Committer) -> str |
web.WerkzeugResponse | tuple[Mapping[str, Any], int]:
return await _keys_update(session)
@admin.post("/keys/update")
-async def keys_update_post(session: web.Committer) -> str | response.Response
| tuple[Mapping[str, Any], int]:
+async def keys_update_post(session: web.Committer) -> str |
web.WerkzeugResponse | tuple[Mapping[str, Any], int]:
return await _keys_update(session)
-async def _keys_update(session: web.Committer) -> str | response.Response |
tuple[Mapping[str, Any], int]:
+async def _keys_update(session: web.Committer) -> str | web.WerkzeugResponse |
tuple[Mapping[str, Any], int]:
"""Update keys from remote data."""
if quart.request.method != "POST":
empty_form = await forms.Empty.create_form()
@@ -582,20 +581,20 @@ async def _ldap(session: web.Committer) -> str:
@admin.get("/ongoing-tasks/<project_name>/<version_name>/<revision>")
async def ongoing_tasks_get(
session: web.Committer, project_name: str, version_name: str, revision: str
-) -> quart.wrappers.response.Response:
+) -> web.QuartResponse:
return await _ongoing_tasks(session, project_name, version_name, revision)
@admin.post("/ongoing-tasks/<project_name>/<version_name>/<revision>")
async def ongoing_tasks_post(
session: web.Committer, project_name: str, version_name: str, revision: str
-) -> quart.wrappers.response.Response:
+) -> web.QuartResponse:
return await _ongoing_tasks(session, project_name, version_name, revision)
async def _ongoing_tasks(
session: web.Committer, project_name: str, version_name: str, revision: str
-) -> quart.wrappers.response.Response:
+) -> web.QuartResponse:
try:
ongoing = await interaction.tasks_ongoing(project_name, version_name,
revision)
return web.TextResponse(str(ongoing))
@@ -686,16 +685,16 @@ async def performance(session: web.Committer) -> str:
@admin.get("/projects/update")
-async def projects_update_get(session: web.Committer) -> str |
response.Response | tuple[Mapping[str, Any], int]:
+async def projects_update_get(session: web.Committer) -> str |
web.WerkzeugResponse | tuple[Mapping[str, Any], int]:
return await _projects_update(session)
@admin.post("/projects/update")
-async def projects_update_post(session: web.Committer) -> str |
response.Response | tuple[Mapping[str, Any], int]:
+async def projects_update_post(session: web.Committer) -> str |
web.WerkzeugResponse | tuple[Mapping[str, Any], int]:
return await _projects_update(session)
-async def _projects_update(session: web.Committer) -> str | response.Response
| tuple[Mapping[str, Any], int]:
+async def _projects_update(session: web.Committer) -> str |
web.WerkzeugResponse | tuple[Mapping[str, Any], int]:
"""Update projects from remote data."""
if quart.request.method == "POST":
try:
@@ -724,7 +723,7 @@ async def tasks_(session: web.Committer) -> str:
@admin.get("/task-times/<project_name>/<version_name>/<revision_number>")
async def task_times(
session: web.Committer, project_name: str, version_name: str,
revision_number: str
-) -> quart.wrappers.response.Response:
+) -> web.QuartResponse:
values = []
async with db.session() as data:
tasks = await data.task(
@@ -740,7 +739,7 @@ async def task_times(
@admin.get("/test")
-async def test(session: web.Committer) -> quart.wrappers.response.Response:
+async def test(session: web.Committer) -> web.QuartResponse:
"""Test the storage layer."""
import atr.storage as storage
@@ -780,7 +779,7 @@ async def toggle_view_get(session: web.Committer) -> str:
@admin.post("/toggle-view")
-async def toggle_view_post(session: web.Committer) -> response.Response:
+async def toggle_view_post(session: web.Committer) -> web.WerkzeugResponse:
await util.validate_empty_form()
app = asfquart.APP
diff --git a/atr/api/__init__.py b/atr/api/__init__.py
index ac23fe7..ac6419e 100644
--- a/atr/api/__init__.py
+++ b/atr/api/__init__.py
@@ -154,7 +154,7 @@ async def checks_ongoing(
ongoing_tasks_count, _latest_revision = await
interaction.tasks_ongoing_revision(project, version, revision)
# TODO: Is there a way to return just an int?
# The ResponseReturnValue type in quart does not allow int
- # And if we use quart.jsonify, we must return quart.Response which
quart_schema tries to validate
+ # And if we use quart.jsonify, we must return web.QuartResponse which
quart_schema tries to validate
# ResponseValue = Union[
# "Response",
# "WerkzeugResponse",
diff --git a/atr/get/announce.py b/atr/get/announce.py
index f2f43ff..3ecdecd 100644
--- a/atr/get/announce.py
+++ b/atr/get/announce.py
@@ -15,7 +15,6 @@
# specific language governing permissions and limitations
# under the License.
-import werkzeug.wrappers.response as response
# TODO: Improve upon the routes_release pattern
import atr.blueprints.get as get
@@ -29,7 +28,7 @@ import atr.web as web
@get.committer("/announce/<project_name>/<version_name>")
-async def selected(session: web.Committer, project_name: str, version_name:
str) -> str | response.Response:
+async def selected(session: web.Committer, project_name: str, version_name:
str) -> str | web.WerkzeugResponse:
"""Allow the user to announce a release preview."""
await session.check_access(project_name)
diff --git a/atr/get/candidate.py b/atr/get/candidate.py
index 3b19391..dcce63c 100644
--- a/atr/get/candidate.py
+++ b/atr/get/candidate.py
@@ -18,7 +18,6 @@
"""candidate.py"""
import asfquart.base as base
-import werkzeug.wrappers.response as response
import atr.blueprints.get as get
import atr.db as db
@@ -30,7 +29,7 @@ import atr.web as web
@get.committer("/candidate/view/<project_name>/<version_name>")
-async def view(session: web.Committer, project_name: str, version_name: str)
-> response.Response | str:
+async def view(session: web.Committer, project_name: str, version_name: str)
-> web.WerkzeugResponse | str:
"""View all the files in the rsync upload directory for a release."""
await session.check_access(project_name)
@@ -67,7 +66,7 @@ async def view(session: web.Committer, project_name: str,
version_name: str) ->
@get.committer("/candidate/view/<project_name>/<version_name>/<path:file_path>")
async def view_path(
session: web.Committer, project_name: str, version_name: str, file_path:
str
-) -> response.Response | str:
+) -> web.WerkzeugResponse | str:
"""View the content of a specific file in the release candidate."""
await session.check_access(project_name)
diff --git a/atr/get/compose.py b/atr/get/compose.py
index 2696b38..304f246 100644
--- a/atr/get/compose.py
+++ b/atr/get/compose.py
@@ -16,7 +16,6 @@
# under the License.
import asfquart.base as base
-import werkzeug.wrappers.response as response
import atr.blueprints.get as get
import atr.db as db
@@ -27,7 +26,7 @@ import atr.web as web
@get.committer("/compose/<project_name>/<version_name>")
-async def selected(session: web.Committer, project_name: str, version_name:
str) -> response.Response | str:
+async def selected(session: web.Committer, project_name: str, version_name:
str) -> web.WerkzeugResponse | str:
"""Show the contents of the release candidate draft."""
await session.check_access(project_name)
diff --git a/atr/get/download.py b/atr/get/download.py
index c1d81ed..f9c6fa9 100644
--- a/atr/get/download.py
+++ b/atr/get/download.py
@@ -22,7 +22,6 @@ import aiofiles
import aiofiles.os
import asfquart.base as base
import quart
-import werkzeug.wrappers.response as response
import zipstream
import atr.blueprints.get as get
@@ -37,7 +36,7 @@ import atr.web as web
@get.committer("/download/all/<project_name>/<version_name>")
-async def all_selected(session: web.Committer, project_name: str,
version_name: str) -> response.Response | str:
+async def all_selected(session: web.Committer, project_name: str,
version_name: str) -> web.WerkzeugResponse | str:
"""Display download commands for a release."""
import atr.get.root as root
@@ -64,25 +63,19 @@ async def all_selected(session: web.Committer,
project_name: str, version_name:
@get.public("/download/path/<project_name>/<version_name>/<path:file_path>")
-async def path(
- session: web.Committer | None, project_name: str, version_name: str,
file_path: str
-) -> response.Response | quart.Response:
+async def path(session: web.Committer | None, project_name: str, version_name:
str, file_path: str) -> web.Response:
"""Download a file or list a directory from a release in any phase."""
return await _download_or_list(project_name, version_name, file_path)
@get.public("/download/path/<project_name>/<version_name>/")
-async def path_empty(
- session: web.Committer | None, project_name: str, version_name: str
-) -> response.Response | quart.Response:
+async def path_empty(session: web.Committer | None, project_name: str,
version_name: str) -> web.Response:
"""List files at the root of a release directory for download."""
return await _download_or_list(project_name, version_name, ".")
@get.public("/download/sh/<project_name>/<version_name>")
-async def sh_selected(
- session: web.Committer | None, project_name: str, version_name: str
-) -> response.Response | quart.Response:
+async def sh_selected(session: web.Committer | None, project_name: str,
version_name: str) -> web.Response:
"""Shell script to download a release."""
conf = config.get()
app_host = conf.APP_HOST
@@ -97,9 +90,7 @@ async def sh_selected(
@get.public("/download/urls/<project_name>/<version_name>")
-async def urls_selected(
- session: web.Committer | None, project_name: str, version_name: str
-) -> response.Response | quart.Response:
+async def urls_selected(session: web.Committer | None, project_name: str,
version_name: str) -> web.Response:
try:
async with db.session() as data:
release = await data.release(project_name=project_name,
version=version_name).demand(
@@ -114,9 +105,7 @@ async def urls_selected(
@get.committer("/download/zip/<project_name>/<version_name>")
-async def zip_selected(
- session: web.Committer, project_name: str, version_name: str
-) -> response.Response | quart.wrappers.response.Response:
+async def zip_selected(session: web.Committer, project_name: str,
version_name: str) -> web.Response:
try:
release = await session.release(project_name=project_name,
version_name=version_name, phase=None)
except ValueError as e:
@@ -146,7 +135,7 @@ async def zip_selected(
return web.ZipResponse(stream_zip(files_to_zip), headers=headers)
-async def _download_or_list(project_name: str, version_name: str, file_path:
str) -> response.Response | quart.Response:
+async def _download_or_list(project_name: str, version_name: str, file_path:
str) -> web.Response:
"""Download a file or list a directory from a release in any phase."""
import atr.get.root as root
@@ -200,7 +189,7 @@ async def _generate_file_url_list(release: sql.Release) ->
str:
async def _list(
original_path: pathlib.Path, full_path: pathlib.Path, project_name: str,
version_name: str, file_path: str
-) -> response.Response | quart.Response:
+) -> web.Response:
# Build a list of files in the directory
files: list[pathlib.Path] = []
for file in await aiofiles.os.listdir(full_path):
diff --git a/atr/get/draft.py b/atr/get/draft.py
index ca9ad87..daa028a 100644
--- a/atr/get/draft.py
+++ b/atr/get/draft.py
@@ -19,7 +19,6 @@ from __future__ import annotations
import datetime
import pathlib
-from typing import TYPE_CHECKING
import aiofiles.os
import asfquart.base as base
@@ -30,9 +29,6 @@ import atr.template as template
import atr.util as util
import atr.web as web
-if TYPE_CHECKING:
- import werkzeug.wrappers.response as response
-
@get.committer("/draft/tools/<project_name>/<version_name>/<path:file_path>")
async def tools(session: web.Committer, project_name: str, version_name: str,
file_path: str) -> str:
@@ -71,7 +67,7 @@ async def tools(session: web.Committer, project_name: str,
version_name: str, fi
# TODO: Should we deprecate this and ensure compose covers it all?
# If we did that, we'd lose the exhaustive use of the abstraction
@get.committer("/draft/view/<project_name>/<version_name>")
-async def view(session: web.Committer, project_name: str, version_name: str)
-> response.Response | str:
+async def view(session: web.Committer, project_name: str, version_name: str)
-> web.WerkzeugResponse | str:
"""View all the files in the rsync upload directory for a release."""
await session.check_access(project_name)
diff --git a/atr/get/file.py b/atr/get/file.py
index 545ab9e..c8ccd79 100644
--- a/atr/get/file.py
+++ b/atr/get/file.py
@@ -15,7 +15,6 @@
# specific language governing permissions and limitations
# under the License.
-import werkzeug.wrappers.response as response
import atr.blueprints.get as get
import atr.template as template
@@ -26,7 +25,7 @@ import atr.web as web
@get.committer("/file/<project_name>/<version_name>/<path:file_path>")
async def selected_path(
session: web.Committer, project_name: str, version_name: str, file_path:
str
-) -> response.Response | str:
+) -> web.WerkzeugResponse | str:
"""View the content of a specific file in the release candidate draft."""
# TODO: Make this independent of the release phase
await session.check_access(project_name)
diff --git a/atr/get/finish.py b/atr/get/finish.py
index 9530bad..d0f015b 100644
--- a/atr/get/finish.py
+++ b/atr/get/finish.py
@@ -16,9 +16,6 @@
# under the License.
-import quart.wrappers.response as quart_response
-import werkzeug.wrappers.response as response
-
import atr.blueprints.get as get
import atr.shared as shared
import atr.web as web
@@ -27,6 +24,6 @@ import atr.web as web
@get.committer("/finish/<project_name>/<version_name>")
async def selected(
session: web.Committer, project_name: str, version_name: str
-) -> tuple[quart_response.Response, int] | response.Response | str:
+) -> tuple[web.QuartResponse, int] | web.WerkzeugResponse | str:
"""Finish a release preview."""
return await shared.finish.selected(session, project_name, version_name)
diff --git a/atr/get/ignores.py b/atr/get/ignores.py
index 517509d..e32e604 100644
--- a/atr/get/ignores.py
+++ b/atr/get/ignores.py
@@ -18,7 +18,6 @@
from typing import Final
import markupsafe
-import werkzeug.wrappers.response as response
import wtforms
import atr.blueprints.get as get
@@ -51,7 +50,7 @@ document.querySelectorAll("table.page-details
input.form-control").forEach(funct
@get.committer("/ignores/<committee_name>")
-async def ignores(session: web.Committer, committee_name: str) -> str |
response.Response:
+async def ignores(session: web.Committer, committee_name: str) -> str |
web.WerkzeugResponse:
async with storage.read() as read:
ragp = read.as_general_public()
ignores = await ragp.checks.ignores(committee_name)
diff --git a/atr/get/keys.py b/atr/get/keys.py
index 0cbd946..7f72def 100644
--- a/atr/get/keys.py
+++ b/atr/get/keys.py
@@ -19,7 +19,6 @@ import datetime
import asfquart as asfquart
import quart
-import werkzeug.wrappers.response as response
import atr.blueprints.get as get
import atr.db as db
@@ -37,7 +36,7 @@ async def add(session: web.Committer) -> str:
@get.committer("/keys/details/<fingerprint>")
-async def details(session: web.Committer, fingerprint: str) -> str |
response.Response:
+async def details(session: web.Committer, fingerprint: str) -> str |
web.WerkzeugResponse:
"""Display details for a specific OpenPGP key."""
return await shared.keys.details(session, fingerprint)
@@ -88,7 +87,7 @@ async def keys(session: web.Committer) -> str:
@get.committer("/keys/ssh/add")
-async def ssh_add(session: web.Committer) -> response.Response | str:
+async def ssh_add(session: web.Committer) -> web.WerkzeugResponse | str:
"""Add a new SSH key to the user's account."""
return await shared.keys.ssh_add(session)
diff --git a/atr/get/preview.py b/atr/get/preview.py
index 0a9689b..0e8df81 100644
--- a/atr/get/preview.py
+++ b/atr/get/preview.py
@@ -15,7 +15,6 @@
# specific language governing permissions and limitations
# under the License.
-import werkzeug.wrappers.response as response
import atr.blueprints.get as get
import atr.models.sql as sql
@@ -25,7 +24,7 @@ import atr.web as web
@get.committer("/preview/view/<project_name>/<version_name>")
-async def view(session: web.Committer, project_name: str, version_name: str)
-> response.Response | str:
+async def view(session: web.Committer, project_name: str, version_name: str)
-> web.WerkzeugResponse | str:
"""View all the files in the rsync upload directory for a release."""
await session.check_access(project_name)
@@ -58,7 +57,7 @@ async def view(session: web.Committer, project_name: str,
version_name: str) ->
@get.committer("/preview/view/<project_name>/<version_name>/<path:file_path>")
async def view_path(
session: web.Committer, project_name: str, version_name: str, file_path:
str
-) -> response.Response | str:
+) -> web.WerkzeugResponse | str:
"""View the content of a specific file in the release preview."""
await session.check_access(project_name)
diff --git a/atr/get/projects.py b/atr/get/projects.py
index 5a6d682..2e4dec1 100644
--- a/atr/get/projects.py
+++ b/atr/get/projects.py
@@ -17,8 +17,6 @@
from __future__ import annotations
-from typing import TYPE_CHECKING
-
import atr.blueprints.get as get
import atr.config as config
import atr.db as db
@@ -28,12 +26,9 @@ import atr.shared as shared
import atr.template as template
import atr.web as web
-if TYPE_CHECKING:
- import werkzeug.wrappers.response as response
-
@get.committer("/project/add/<committee_name>")
-async def add_project(session: web.Committer, committee_name: str) ->
response.Response | str:
+async def add_project(session: web.Committer, committee_name: str) ->
web.WerkzeugResponse | str:
return await shared.projects.add_project(session, committee_name)
@@ -72,5 +67,5 @@ async def select(session: web.Committer) -> str:
@get.committer("/projects/<name>")
-async def view(session: web.Committer, name: str) -> response.Response | str:
+async def view(session: web.Committer, name: str) -> web.WerkzeugResponse |
str:
return await shared.projects.view(session, name)
diff --git a/atr/get/published.py b/atr/get/published.py
index 6d7e572..ad5c959 100644
--- a/atr/get/published.py
+++ b/atr/get/published.py
@@ -29,7 +29,7 @@ import atr.web as web
@get.committer("/published/<path:path>")
-async def path(session: web.Committer, path: str) -> quart.Response:
+async def path(session: web.Committer, path: str) -> web.QuartResponse:
"""View the content of a specific file in the downloads directory."""
# This route is for debugging
# When developing locally, there is no proxy to view the downloads
directory
@@ -38,7 +38,7 @@ async def path(session: web.Committer, path: str) ->
quart.Response:
@get.committer("/published/")
-async def root(session: web.Committer) -> quart.Response:
+async def root(session: web.Committer) -> web.QuartResponse:
return await _path(session, "")
@@ -91,11 +91,11 @@ async def _directory_listing_pre(full_path: pathlib.Path,
current_path: str, pre
pre.text("\n")
-async def _file_content(full_path: pathlib.Path) -> quart.Response:
+async def _file_content(full_path: pathlib.Path) -> web.QuartResponse:
return await quart.send_file(full_path)
-async def _path(session: web.Committer, path: str) -> quart.Response:
+async def _path(session: web.Committer, path: str) -> web.QuartResponse:
downloads_path = util.get_downloads_dir()
full_path = downloads_path / path
if await aiofiles.os.path.isdir(full_path):
diff --git a/atr/get/ref.py b/atr/get/ref.py
index 78dcbef..807b050 100644
--- a/atr/get/ref.py
+++ b/atr/get/ref.py
@@ -19,7 +19,6 @@ import ast
import pathlib
import quart
-import werkzeug.wrappers.response as response
import atr.blueprints.get as get
import atr.config as config
@@ -31,7 +30,7 @@ import atr.web as web
@get.public("/ref/<path:ref_path>")
-async def resolve(session: web.Committer | None, ref_path: str) ->
response.Response:
+async def resolve(session: web.Committer | None, ref_path: str) ->
web.WerkzeugResponse:
project_root = pathlib.Path(config.get().PROJECT_ROOT)
if ":" in ref_path:
diff --git a/atr/get/release.py b/atr/get/release.py
index dac1e8a..4c17f9c 100644
--- a/atr/get/release.py
+++ b/atr/get/release.py
@@ -18,7 +18,6 @@
import datetime
import asfquart.base as base
-import werkzeug.wrappers.response as response
import atr.blueprints.get as get
import atr.db as db
@@ -94,7 +93,7 @@ async def select(session: web.Committer, project_name: str)
-> str:
@get.public("/release/view/<project_name>/<version_name>")
-async def view(session: web.Committer | None, project_name: str, version_name:
str) -> response.Response | str:
+async def view(session: web.Committer | None, project_name: str, version_name:
str) -> web.WerkzeugResponse | str:
"""View all the files in the rsync upload directory for a release."""
async with db.session() as data:
release_name = sql.release_name(project_name, version_name)
@@ -123,7 +122,7 @@ async def view(session: web.Committer | None, project_name:
str, version_name: s
@get.public("/release/view/<project_name>/<version_name>/<path:file_path>")
async def view_path(
session: web.Committer | None, project_name: str, version_name: str,
file_path: str
-) -> response.Response | str:
+) -> web.WerkzeugResponse | str:
"""View the content of a specific file in the final release."""
async with db.session() as data:
release_name = sql.release_name(project_name, version_name)
diff --git a/atr/get/root.py b/atr/get/root.py
index 6fd33b5..0fa35c2 100644
--- a/atr/get/root.py
+++ b/atr/get/root.py
@@ -24,7 +24,6 @@ import asfquart.session
import quart.wrappers.response as quart_response
import sqlalchemy.orm as orm
import sqlmodel
-import werkzeug.wrappers.response as response
import atr.blueprints.get as get
import atr.config as config
@@ -155,7 +154,7 @@ async def policies(session: web.Committer | None) -> str:
@get.public("/test-login")
-async def test_login(session: web.Committer | None) -> response.Response:
+async def test_login(session: web.Committer | None) -> web.WerkzeugResponse:
if not config.get().ALLOW_TESTS:
raise base.ASFQuartException("Test login not enabled", errorcode=404)
diff --git a/atr/get/start.py b/atr/get/start.py
index 1ebbb7d..69b7f68 100644
--- a/atr/get/start.py
+++ b/atr/get/start.py
@@ -16,14 +16,12 @@
# under the License.
-import werkzeug.wrappers.response as response
-
import atr.blueprints.get as get
import atr.shared as shared
import atr.web as web
@get.committer("/start/<project_name>")
-async def selected(session: web.Committer, project_name: str) ->
response.Response | str:
+async def selected(session: web.Committer, project_name: str) ->
web.WerkzeugResponse | str:
"""Allow the user to start a new release draft, or handle its
submission."""
return await shared.start.selected(session, project_name)
diff --git a/atr/get/tokens.py b/atr/get/tokens.py
index 8425c0c..21a8d18 100644
--- a/atr/get/tokens.py
+++ b/atr/get/tokens.py
@@ -16,13 +16,11 @@
# under the License.
-import werkzeug.wrappers.response as response
-
import atr.blueprints.get as get
import atr.shared as shared
import atr.web as web
@get.committer("/tokens")
-async def tokens(session: web.Committer) -> str | response.Response:
+async def tokens(session: web.Committer) -> str | web.WerkzeugResponse:
return await shared.tokens.tokens(session)
diff --git a/atr/get/upload.py b/atr/get/upload.py
index d4ce256..09fb5b3 100644
--- a/atr/get/upload.py
+++ b/atr/get/upload.py
@@ -16,13 +16,11 @@
# under the License.
-import werkzeug.wrappers.response as response
-
import atr.blueprints.get as get
import atr.shared as shared
import atr.web as web
@get.committer("/upload/<project_name>/<version_name>")
-async def selected(session: web.Committer, project_name: str, version_name:
str) -> response.Response | str:
+async def selected(session: web.Committer, project_name: str, version_name:
str) -> web.WerkzeugResponse | str:
return await shared.upload.selected(session, project_name, version_name)
diff --git a/atr/get/vote.py b/atr/get/vote.py
index f2da908..9cd6b3a 100644
--- a/atr/get/vote.py
+++ b/atr/get/vote.py
@@ -16,7 +16,6 @@
# under the License.
import asfquart.base as base
-import werkzeug.wrappers.response as response
import atr.blueprints.get as get
import atr.db as db
@@ -34,7 +33,7 @@ import atr.web as web
@get.public("/vote/<project_name>/<version_name>")
-async def selected(session: web.Committer | None, project_name: str,
version_name: str) -> response.Response | str:
+async def selected(session: web.Committer | None, project_name: str,
version_name: str) -> web.WerkzeugResponse | str:
"""Show the contents of the release candidate draft."""
async with db.session() as data:
release = await data.release(
diff --git a/atr/get/voting.py b/atr/get/voting.py
index 2d4dc05..2334696 100644
--- a/atr/get/voting.py
+++ b/atr/get/voting.py
@@ -16,8 +16,6 @@
# under the License.
-import werkzeug.wrappers.response as response
-
import atr.blueprints.get as get
import atr.shared as shared
import atr.web as web
@@ -26,5 +24,5 @@ import atr.web as web
@get.committer("/voting/<project_name>/<version_name>/<revision>")
async def selected_revision(
session: web.Committer, project_name: str, version_name: str, revision: str
-) -> response.Response | str:
+) -> web.WerkzeugResponse | str:
return await shared.voting.selected_revision(session, project_name,
version_name, revision)
diff --git a/atr/post/announce.py b/atr/post/announce.py
index 176d0af..3c68862 100644
--- a/atr/post/announce.py
+++ b/atr/post/announce.py
@@ -17,13 +17,8 @@
from __future__ import annotations
-from typing import TYPE_CHECKING
-
import quart
-if TYPE_CHECKING:
- import werkzeug.wrappers.response as response
-
# TODO: Improve upon the routes_release pattern
import atr.blueprints.post as post
import atr.models.sql as sql
@@ -39,7 +34,7 @@ class AnnounceError(Exception):
@post.committer("/announce/<project_name>/<version_name>")
-async def selected(session: web.Committer, project_name: str, version_name:
str) -> str | response.Response:
+async def selected(session: web.Committer, project_name: str, version_name:
str) -> str | web.WerkzeugResponse:
"""Handle the announcement form submission and promote the preview to
release."""
import atr.get as get
diff --git a/atr/post/candidate.py b/atr/post/candidate.py
index 1f2a426..8eefe62 100644
--- a/atr/post/candidate.py
+++ b/atr/post/candidate.py
@@ -15,14 +15,12 @@
# specific language governing permissions and limitations
# under the License.
-import werkzeug.wrappers.response as response
-
import atr.blueprints.post as post
import atr.web as web
@post.committer("/candidate/delete")
-async def delete(session: web.Committer) -> response.Response:
+async def delete(session: web.Committer) -> web.WerkzeugResponse:
"""Delete a release candidate."""
import atr.get as get
diff --git a/atr/post/distribution.py b/atr/post/distribution.py
index dbf1744..132cac3 100644
--- a/atr/post/distribution.py
+++ b/atr/post/distribution.py
@@ -17,8 +17,6 @@
from __future__ import annotations
-from typing import TYPE_CHECKING
-
import quart
import atr.blueprints.post as post
@@ -29,12 +27,9 @@ import atr.shared as shared
import atr.storage as storage
import atr.web as web
-if TYPE_CHECKING:
- import werkzeug.wrappers.response as response
-
@post.committer("/distribution/delete/<project>/<version>")
-async def delete(session: web.Committer, project: str, version: str) ->
response.Response:
+async def delete(session: web.Committer, project: str, version: str) ->
web.WerkzeugResponse:
form = await shared.distribution.DeleteForm.create_form(data=await
quart.request.form)
dd = distribution.DeleteData.model_validate(form.data)
diff --git a/atr/post/draft.py b/atr/post/draft.py
index e54da85..8fd7502 100644
--- a/atr/post/draft.py
+++ b/atr/post/draft.py
@@ -18,7 +18,6 @@
from __future__ import annotations
import pathlib
-from typing import TYPE_CHECKING
import aiofiles.os
import aioshutil
@@ -36,9 +35,6 @@ import atr.storage as storage
import atr.util as util
import atr.web as web
-if TYPE_CHECKING:
- import werkzeug.wrappers.response as response
-
class VotePreviewForm(forms.Typed):
body = forms.textarea("Body")
@@ -49,7 +45,7 @@ class VotePreviewForm(forms.Typed):
@post.committer("/draft/delete")
-async def delete(session: web.Committer) -> response.Response:
+async def delete(session: web.Committer) -> web.WerkzeugResponse:
"""Delete a candidate draft and all its associated files."""
import atr.get as get
@@ -95,7 +91,7 @@ async def delete(session: web.Committer) -> response.Response:
@post.committer("/draft/delete-file/<project_name>/<version_name>")
-async def delete_file(session: web.Committer, project_name: str, version_name:
str) -> response.Response:
+async def delete_file(session: web.Committer, project_name: str, version_name:
str) -> web.WerkzeugResponse:
"""Delete a specific file from the release candidate, creating a new
revision."""
await session.check_access(project_name)
@@ -130,7 +126,7 @@ async def delete_file(session: web.Committer, project_name:
str, version_name: s
@post.committer("/draft/fresh/<project_name>/<version_name>")
-async def fresh(session: web.Committer, project_name: str, version_name: str)
-> response.Response:
+async def fresh(session: web.Committer, project_name: str, version_name: str)
-> web.WerkzeugResponse:
"""Restart all checks for a whole release candidate draft."""
# Admin only button, but it's okay if users find and use this manually
await session.check_access(project_name)
@@ -156,7 +152,7 @@ async def fresh(session: web.Committer, project_name: str,
version_name: str) ->
@post.committer("/draft/hashgen/<project_name>/<version_name>/<path:file_path>")
-async def hashgen(session: web.Committer, project_name: str, version_name:
str, file_path: str) -> response.Response:
+async def hashgen(session: web.Committer, project_name: str, version_name:
str, file_path: str) -> web.WerkzeugResponse:
"""Generate an sha256 or sha512 hash file for a candidate draft file,
creating a new revision."""
await session.check_access(project_name)
@@ -189,7 +185,7 @@ async def hashgen(session: web.Committer, project_name:
str, version_name: str,
@post.committer("/draft/sbomgen/<project_name>/<version_name>/<path:file_path>")
-async def sbomgen(session: web.Committer, project_name: str, version_name:
str, file_path: str) -> response.Response:
+async def sbomgen(session: web.Committer, project_name: str, version_name:
str, file_path: str) -> web.WerkzeugResponse:
"""Generate a CycloneDX SBOM file for a candidate draft file, creating a
new revision."""
await session.check_access(project_name)
@@ -246,7 +242,7 @@ async def sbomgen(session: web.Committer, project_name:
str, version_name: str,
@post.committer("/draft/svnload/<project_name>/<version_name>")
-async def svnload(session: web.Committer, project_name: str, version_name:
str) -> response.Response | str:
+async def svnload(session: web.Committer, project_name: str, version_name:
str) -> web.WerkzeugResponse | str:
"""Import files from SVN into a draft."""
await session.check_access(project_name)
@@ -293,7 +289,7 @@ async def svnload(session: web.Committer, project_name:
str, version_name: str)
@post.committer("/draft/vote/preview/<project_name>/<version_name>")
async def vote_preview(
session: web.Committer, project_name: str, version_name: str
-) -> quart.wrappers.response.Response | response.Response | str:
+) -> web.QuartResponse | web.WerkzeugResponse | str:
"""Show the vote email preview for a release."""
import atr.get as get
diff --git a/atr/post/finish.py b/atr/post/finish.py
index 4ea8b0e..356f095 100644
--- a/atr/post/finish.py
+++ b/atr/post/finish.py
@@ -17,19 +17,16 @@
from collections.abc import Awaitable, Callable
-import quart.wrappers.response as quart_response
-import werkzeug.wrappers.response as response
-
import atr.blueprints.post as post
import atr.shared as shared
import atr.web as web
-type Respond = Callable[[int, str], Awaitable[tuple[quart_response.Response,
int] | response.Response]]
+type Respond = Callable[[int, str], Awaitable[tuple[web.QuartResponse, int] |
web.WerkzeugResponse]]
@post.committer("/finish/<project_name>/<version_name>")
async def selected(
session: web.Committer, project_name: str, version_name: str
-) -> tuple[quart_response.Response, int] | response.Response | str:
+) -> tuple[web.QuartResponse, int] | web.WerkzeugResponse | str:
"""Finish a release preview."""
return await shared.finish.selected(session, project_name, version_name)
diff --git a/atr/post/ignores.py b/atr/post/ignores.py
index 647da04..988a396 100644
--- a/atr/post/ignores.py
+++ b/atr/post/ignores.py
@@ -17,7 +17,6 @@
import quart
-import werkzeug.wrappers.response as response
import atr.blueprints.post as post
import atr.get as get
@@ -28,7 +27,7 @@ import atr.web as web
@post.committer("/ignores/<committee_name>/add")
-async def ignores_committee_add(session: web.Committer, committee_name: str)
-> str | response.Response:
+async def ignores_committee_add(session: web.Committer, committee_name: str)
-> str | web.WerkzeugResponse:
data = await quart.request.form
form = await shared.ignores.AddIgnoreForm.create_form(data=data)
if not (await form.validate_on_submit()):
@@ -56,7 +55,7 @@ async def ignores_committee_add(session: web.Committer,
committee_name: str) ->
@post.committer("/ignores/<committee_name>/delete")
-async def ignores_committee_delete(session: web.Committer, committee_name:
str) -> str | response.Response:
+async def ignores_committee_delete(session: web.Committer, committee_name:
str) -> str | web.WerkzeugResponse:
data = await quart.request.form
form = await shared.ignores.DeleteIgnoreForm.create_form(data=data)
if not (await form.validate_on_submit()):
@@ -86,7 +85,7 @@ async def ignores_committee_delete(session: web.Committer,
committee_name: str)
@post.committer("/ignores/<committee_name>/update")
-async def ignores_committee_update(session: web.Committer, committee_name:
str) -> str | response.Response:
+async def ignores_committee_update(session: web.Committer, committee_name:
str) -> str | web.WerkzeugResponse:
data = await quart.request.form
form = await shared.ignores.UpdateIgnoreForm.create_form(data=data)
if not (await form.validate_on_submit()):
diff --git a/atr/post/keys.py b/atr/post/keys.py
index 246ef6f..1c13692 100644
--- a/atr/post/keys.py
+++ b/atr/post/keys.py
@@ -18,7 +18,6 @@
import asfquart as asfquart
import quart
-import werkzeug.wrappers.response as response
import atr.blueprints.post as post
import atr.get as get
@@ -38,7 +37,7 @@ async def add(session: web.Committer) -> str:
@post.committer("/keys/delete")
-async def delete(session: web.Committer) -> response.Response:
+async def delete(session: web.Committer) -> web.WerkzeugResponse:
"""Delete a public signing key or SSH key from the user's account."""
form = await shared.keys.DeleteKeyForm.create_form(data=await
quart.request.form)
@@ -70,13 +69,15 @@ async def delete(session: web.Committer) ->
response.Response:
@post.committer("/keys/details/<fingerprint>")
-async def details(session: web.Committer, fingerprint: str) -> str |
response.Response:
+async def details(session: web.Committer, fingerprint: str) -> str |
web.WerkzeugResponse:
"""Display details for a specific OpenPGP key."""
return await shared.keys.details(session, fingerprint)
@post.committer("/keys/import/<project_name>/<version_name>")
-async def import_selected_revision(session: web.Committer, project_name: str,
version_name: str) -> response.Response:
+async def import_selected_revision(
+ session: web.Committer, project_name: str, version_name: str
+) -> web.WerkzeugResponse:
await util.validate_empty_form()
async with storage.write() as write:
@@ -95,13 +96,13 @@ async def import_selected_revision(session: web.Committer,
project_name: str, ve
@post.committer("/keys/ssh/add")
-async def ssh_add(session: web.Committer) -> response.Response | str:
+async def ssh_add(session: web.Committer) -> web.WerkzeugResponse | str:
"""Add a new SSH key to the user's account."""
return await shared.keys.ssh_add(session)
@post.committer("/keys/update-committee-keys/<committee_name>")
-async def update_committee_keys(session: web.Committer, committee_name: str)
-> response.Response:
+async def update_committee_keys(session: web.Committer, committee_name: str)
-> web.WerkzeugResponse:
"""Generate and save the KEYS file for a specific committee."""
form = await shared.keys.UpdateCommitteeKeysForm.create_form()
if not await form.validate_on_submit():
diff --git a/atr/post/preview.py b/atr/post/preview.py
index 7bc2f6d..d036a23 100644
--- a/atr/post/preview.py
+++ b/atr/post/preview.py
@@ -16,7 +16,6 @@
# under the License.
import quart
-import werkzeug.wrappers.response as response
import atr.blueprints.post as post
import atr.construct as construct
@@ -45,9 +44,7 @@ class DeleteForm(forms.Typed):
@post.committer("/preview/announce/<project_name>/<version_name>")
-async def announce_preview(
- session: web.Committer, project_name: str, version_name: str
-) -> quart.wrappers.response.Response | str:
+async def announce_preview(session: web.Committer, project_name: str,
version_name: str) -> web.QuartResponse | str:
"""Generate a preview of the announcement email body."""
# TODO: Where does this come from? A static template?
@@ -77,7 +74,7 @@ async def announce_preview(
@post.committer("/preview/delete")
-async def delete(session: web.Committer) -> response.Response:
+async def delete(session: web.Committer) -> web.WerkzeugResponse:
"""Delete a preview and all its associated files."""
import atr.get.root as root
diff --git a/atr/post/projects.py b/atr/post/projects.py
index 21626af..5ce94c1 100644
--- a/atr/post/projects.py
+++ b/atr/post/projects.py
@@ -17,8 +17,6 @@
from __future__ import annotations
-from typing import TYPE_CHECKING
-
import quart
import atr.blueprints.post as post
@@ -28,17 +26,14 @@ import atr.storage as storage
import atr.util as util
import atr.web as web
-if TYPE_CHECKING:
- import werkzeug.wrappers.response as response
-
@post.committer("/project/add/<committee_name>")
-async def add_project(session: web.Committer, committee_name: str) ->
response.Response | str:
+async def add_project(session: web.Committer, committee_name: str) ->
web.WerkzeugResponse | str:
return await shared.projects.add_project(session, committee_name)
@post.committer("/project/delete")
-async def delete(session: web.Committer) -> response.Response:
+async def delete(session: web.Committer) -> web.WerkzeugResponse:
"""Delete a project created by the user."""
# TODO: This is not truly empty, so make a form object for this
await util.validate_empty_form()
@@ -60,5 +55,5 @@ async def delete(session: web.Committer) -> response.Response:
@post.committer("/projects/<name>")
-async def view(session: web.Committer, name: str) -> response.Response | str:
+async def view(session: web.Committer, name: str) -> web.WerkzeugResponse |
str:
return await shared.projects.view(session, name)
diff --git a/atr/post/resolve.py b/atr/post/resolve.py
index c85dcf8..98a3cfc 100644
--- a/atr/post/resolve.py
+++ b/atr/post/resolve.py
@@ -17,7 +17,6 @@
import quart
-import werkzeug.wrappers.response as response
import atr.blueprints.post as post
import atr.db.interaction as interaction
@@ -33,7 +32,9 @@ import atr.web as web
@post.committer("/resolve/manual/<project_name>/<version_name>")
-async def manual_selected_post(session: web.Committer, project_name: str,
version_name: str) -> response.Response | str:
+async def manual_selected_post(
+ session: web.Committer, project_name: str, version_name: str
+) -> web.WerkzeugResponse | str:
"""Post the manual vote resolution page."""
await session.check_access(project_name)
release = await session.release(
@@ -71,7 +72,7 @@ async def manual_selected_post(session: web.Committer,
project_name: str, versio
@post.committer("/resolve/submit/<project_name>/<version_name>")
-async def submit_selected(session: web.Committer, project_name: str,
version_name: str) -> response.Response | str:
+async def submit_selected(session: web.Committer, project_name: str,
version_name: str) -> web.WerkzeugResponse | str:
"""Resolve a vote."""
await session.check_access(project_name)
diff --git a/atr/post/revisions.py b/atr/post/revisions.py
index 51e0faa..effc0be 100644
--- a/atr/post/revisions.py
+++ b/atr/post/revisions.py
@@ -19,7 +19,6 @@
import aioshutil
import asfquart.base as base
import quart
-import werkzeug.wrappers.response as response
import atr.blueprints.post as post
import atr.db as db
@@ -31,7 +30,7 @@ import atr.web as web
@post.committer("/revisions/<project_name>/<version_name>")
-async def selected_post(session: web.Committer, project_name: str,
version_name: str) -> response.Response:
+async def selected_post(session: web.Committer, project_name: str,
version_name: str) -> web.WerkzeugResponse:
"""Set a specific revision as the latest for a candidate draft or release
preview."""
await session.check_access(project_name)
diff --git a/atr/post/sbom.py b/atr/post/sbom.py
index 354407a..4911009 100644
--- a/atr/post/sbom.py
+++ b/atr/post/sbom.py
@@ -18,7 +18,6 @@
from __future__ import annotations
import pathlib
-from typing import TYPE_CHECKING
import asfquart.base as base
import quart
@@ -31,12 +30,9 @@ import atr.storage as storage
import atr.util as util
import atr.web as web
-if TYPE_CHECKING:
- import werkzeug.wrappers.response as response
-
@post.committer("/sbom/augment/<project_name>/<version_name>/<path:file_path>")
-async def augment(session: web.Committer, project_name: str, version_name:
str, file_path: str) -> response.Response:
+async def augment(session: web.Committer, project_name: str, version_name:
str, file_path: str) -> web.WerkzeugResponse:
"""Augment a CycloneDX SBOM file."""
await session.check_access(project_name)
@@ -79,7 +75,7 @@ async def augment(session: web.Committer, project_name: str,
version_name: str,
@post.committer("/sbom/scan/<project_name>/<version_name>/<path:file_path>")
-async def scan(session: web.Committer, project_name: str, version_name: str,
file_path: str) -> response.Response:
+async def scan(session: web.Committer, project_name: str, version_name: str,
file_path: str) -> web.WerkzeugResponse:
"""Scan a CycloneDX SBOM file for vulnerabilities using OSV."""
await session.check_access(project_name)
diff --git a/atr/post/start.py b/atr/post/start.py
index bc801e5..bb3aeb8 100644
--- a/atr/post/start.py
+++ b/atr/post/start.py
@@ -16,14 +16,12 @@
# under the License.
-import werkzeug.wrappers.response as response
-
import atr.blueprints.post as post
import atr.shared as shared
import atr.web as web
@post.committer("/start/<project_name>")
-async def selected(session: web.Committer, project_name: str) ->
response.Response | str:
+async def selected(session: web.Committer, project_name: str) ->
web.WerkzeugResponse | str:
"""Allow the user to start a new release draft, or handle its
submission."""
return await shared.start.selected(session, project_name)
diff --git a/atr/post/tokens.py b/atr/post/tokens.py
index 9482bf6..cae3e60 100644
--- a/atr/post/tokens.py
+++ b/atr/post/tokens.py
@@ -16,9 +16,6 @@
# under the License.
-import quart
-import werkzeug.wrappers.response as response
-
import atr.blueprints.post as post
import atr.jwtoken as jwtoken
import atr.shared as shared
@@ -27,7 +24,7 @@ import atr.web as web
@post.committer("/tokens/jwt")
-async def jwt_post(session: web.Committer) -> quart.Response:
+async def jwt_post(session: web.Committer) -> web.QuartResponse:
await util.validate_empty_form()
jwt_token = jwtoken.issue(session.uid)
@@ -35,5 +32,5 @@ async def jwt_post(session: web.Committer) -> quart.Response:
@post.committer("/tokens")
-async def tokens(session: web.Committer) -> str | response.Response:
+async def tokens(session: web.Committer) -> str | web.WerkzeugResponse:
return await shared.tokens.tokens(session)
diff --git a/atr/post/upload.py b/atr/post/upload.py
index 0d14c9b..5eb0f37 100644
--- a/atr/post/upload.py
+++ b/atr/post/upload.py
@@ -16,13 +16,11 @@
# under the License.
-import werkzeug.wrappers.response as response
-
import atr.blueprints.post as post
import atr.shared as shared
import atr.web as web
@post.committer("/upload/<project_name>/<version_name>")
-async def selected(session: web.Committer, project_name: str, version_name:
str) -> response.Response | str:
+async def selected(session: web.Committer, project_name: str, version_name:
str) -> web.WerkzeugResponse | str:
return await shared.upload.selected(session, project_name, version_name)
diff --git a/atr/post/user.py b/atr/post/user.py
index 8db3963..aaf149a 100644
--- a/atr/post/user.py
+++ b/atr/post/user.py
@@ -17,7 +17,6 @@
import quart
-import werkzeug.wrappers.response as response
import atr.blueprints.post as post
import atr.get as get
@@ -27,7 +26,7 @@ import atr.web as web
@post.committer("/user/cache")
-async def session_post(session: web.Committer) -> response.Response:
+async def session_post(session: web.Committer) -> web.WerkzeugResponse:
form_data = await quart.request.form
cache_form = await shared.user.CacheForm.create_form(data=form_data)
diff --git a/atr/post/vote.py b/atr/post/vote.py
index a03da6d..81afd69 100644
--- a/atr/post/vote.py
+++ b/atr/post/vote.py
@@ -16,7 +16,6 @@
# under the License.
import quart
-import werkzeug.wrappers.response as response
import atr.blueprints.post as post
import atr.forms as forms
@@ -28,7 +27,7 @@ import atr.web as web
@post.committer("/vote/<project_name>/<version_name>")
-async def selected_post(session: web.Committer, project_name: str,
version_name: str) -> response.Response:
+async def selected_post(session: web.Committer, project_name: str,
version_name: str) -> web.WerkzeugResponse:
"""Handle submission of a vote."""
await session.check_access(project_name)
diff --git a/atr/post/voting.py b/atr/post/voting.py
index 69dd0f3..11ab5be 100644
--- a/atr/post/voting.py
+++ b/atr/post/voting.py
@@ -16,8 +16,6 @@
# under the License.
-import werkzeug.wrappers.response as response
-
import atr.blueprints.post as post
import atr.shared as shared
import atr.web as web
@@ -26,6 +24,6 @@ import atr.web as web
@post.committer("/voting/<project_name>/<version_name>/<revision>")
async def selected_revision(
session: web.Committer, project_name: str, version_name: str, revision: str
-) -> response.Response | str:
+) -> web.WerkzeugResponse | str:
"""Show the vote initiation form for a release."""
return await shared.voting.selected_revision(session, project_name,
version_name, revision)
diff --git a/atr/shared/__init__.py b/atr/shared/__init__.py
index 0675e01..a51a194 100644
--- a/atr/shared/__init__.py
+++ b/atr/shared/__init__.py
@@ -17,7 +17,6 @@
from typing import TYPE_CHECKING, Final
-import werkzeug.wrappers.response as response
import wtforms
import atr.db as db
@@ -84,7 +83,7 @@ async def check(
vote_task: sql.Task | None = None,
can_vote: bool = False,
can_resolve: bool = False,
-) -> response.Response | str:
+) -> web.WerkzeugResponse | str:
base_path = util.release_directory(release)
# TODO: This takes 180ms for providers
diff --git a/atr/shared/finish.py b/atr/shared/finish.py
index 8033ea3..d839dd3 100644
--- a/atr/shared/finish.py
+++ b/atr/shared/finish.py
@@ -23,9 +23,7 @@ from typing import Any
import aiofiles.os
import asfquart.base as base
import quart
-import quart.wrappers.response as quart_response
import werkzeug.datastructures as datastructures
-import werkzeug.wrappers.response as response
import wtforms
import wtforms.fields as fields
@@ -40,7 +38,7 @@ import atr.template as template
import atr.util as util
import atr.web as web
-type Respond = Callable[[int, str], Awaitable[tuple[quart_response.Response,
int] | response.Response]]
+type Respond = Callable[[int, str], Awaitable[tuple[web.QuartResponse, int] |
web.WerkzeugResponse]]
class DeleteEmptyDirectoryForm(forms.Typed):
@@ -100,7 +98,7 @@ class RCTagAnalysisResult:
async def selected(
session: web.Committer, project_name: str, version_name: str
-) -> tuple[quart_response.Response, int] | response.Response | str:
+) -> tuple[web.QuartResponse, int] | web.WerkzeugResponse | str:
"""Finish a release preview."""
await session.check_access(project_name)
@@ -109,7 +107,7 @@ async def selected(
async def respond(
http_status: int,
msg: str,
- ) -> tuple[quart_response.Response, int] | response.Response:
+ ) -> tuple[web.QuartResponse, int] | web.WerkzeugResponse:
"""Helper to respond with JSON or flash message and redirect."""
nonlocal session
nonlocal project_name
@@ -248,7 +246,7 @@ async def _delete_empty_directory(
project_name: str,
version_name: str,
respond: Respond,
-) -> tuple[quart_response.Response, int] | response.Response:
+) -> tuple[web.QuartResponse, int] | web.WerkzeugResponse:
try:
async with storage.write(session) as write:
wacp = await write.as_project_committee_member(project_name)
@@ -269,7 +267,7 @@ async def _move_file_to_revision(
project_name: str,
version_name: str,
respond: Respond,
-) -> tuple[quart_response.Response, int] | response.Response:
+) -> tuple[web.QuartResponse, int] | web.WerkzeugResponse:
try:
async with storage.write(session) as write:
wacp = await write.as_project_committee_member(project_name)
@@ -310,7 +308,7 @@ async def _remove_rc_tags(
project_name: str,
version_name: str,
respond: Respond,
-) -> tuple[quart_response.Response, int] | response.Response:
+) -> tuple[web.QuartResponse, int] | web.WerkzeugResponse:
try:
async with storage.write(session) as write:
wacp = await write.as_project_committee_member(project_name)
@@ -362,7 +360,7 @@ async def _sources_and_targets(latest_revision_dir:
pathlib.Path) -> tuple[list[
async def _submission_process(
args: ProcessFormDataArgs,
-) -> tuple[quart_response.Response, int] | response.Response | str | None:
+) -> tuple[web.QuartResponse, int] | web.WerkzeugResponse | str | None:
delete_empty_directory = "submit_delete_empty_dir" in args.formdata
remove_rc_tags = "submit_remove_rc_tags" in args.formdata
move_file = ("source_files" in args.formdata) and ("target_directory" in
args.formdata)
@@ -381,7 +379,7 @@ async def _submission_process(
async def _submission_process_delete_empty_directory(
args: ProcessFormDataArgs,
-) -> tuple[quart_response.Response, int] | response.Response | str | None:
+) -> tuple[web.QuartResponse, int] | web.WerkzeugResponse | str | None:
if await args.delete_dir_form.validate_on_submit():
dir_to_delete_str = args.delete_dir_form.directory_to_delete.data
return await _delete_empty_directory(
@@ -402,7 +400,7 @@ async def _submission_process_delete_empty_directory(
async def _submission_process_move_file(
args: ProcessFormDataArgs,
-) -> tuple[quart_response.Response, int] | response.Response | str | None:
+) -> tuple[web.QuartResponse, int] | web.WerkzeugResponse | str | None:
source_files_data = args.formdata.getlist("source_files")
target_dir_data = args.formdata.get("target_directory")
@@ -419,7 +417,7 @@ async def _submission_process_move_file(
async def _submission_process_remove_rc_tags(
args: ProcessFormDataArgs,
-) -> tuple[quart_response.Response, int] | response.Response | str | None:
+) -> tuple[web.QuartResponse, int] | web.WerkzeugResponse | str | None:
if await args.remove_rc_tags_form.validate_on_submit():
return await _remove_rc_tags(args.session, args.project_name,
args.version_name, args.respond)
elif args.wants_json:
diff --git a/atr/shared/keys.py b/atr/shared/keys.py
index 563f8e8..3446b21 100644
--- a/atr/shared/keys.py
+++ b/atr/shared/keys.py
@@ -26,7 +26,6 @@ import asfquart as asfquart
import asfquart.base as base
import quart
import werkzeug.datastructures as datastructures
-import werkzeug.wrappers.response as response
import wtforms
import atr.db as db
@@ -201,7 +200,7 @@ async def add(session: web.Committer) -> str:
)
-async def details(session: web.Committer, fingerprint: str) -> str |
response.Response:
+async def details(session: web.Committer, fingerprint: str) -> str |
web.WerkzeugResponse:
"""Display details for a specific OpenPGP key."""
fingerprint = fingerprint.lower()
user_committees = []
@@ -263,7 +262,7 @@ async def details(session: web.Committer, fingerprint: str)
-> str | response.Re
)
-async def ssh_add(session: web.Committer) -> response.Response | str:
+async def ssh_add(session: web.Committer) -> web.WerkzeugResponse | str:
"""Add a new SSH key to the user's account."""
# TODO: Make an auth.require wrapper that gives the session automatically
# And the form if it's a POST handler? Might be hard to type
diff --git a/atr/shared/projects.py b/atr/shared/projects.py
index 1a98c87..8cf3ffd 100644
--- a/atr/shared/projects.py
+++ b/atr/shared/projects.py
@@ -20,7 +20,7 @@ from __future__ import annotations
import datetime
import http.client
import re
-from typing import TYPE_CHECKING, Any
+from typing import Any
import asfquart.base as base
import quart
@@ -40,9 +40,6 @@ import atr.user as user
import atr.util as util
import atr.web as web
-if TYPE_CHECKING:
- import werkzeug.wrappers.response as response
-
class AddForm(forms.Typed):
committee_name = forms.hidden()
@@ -229,7 +226,7 @@ class ReleasePolicyForm(forms.Typed):
return not self.errors
-async def add_project(session: web.Committer, committee_name: str) ->
response.Response | str:
+async def add_project(session: web.Committer, committee_name: str) ->
web.WerkzeugResponse | str:
await session.check_access_committee(committee_name)
async with db.session() as data:
@@ -253,7 +250,7 @@ You must start with your committee label, and you must use
lower case.
return await template.render("project-add-project.html", form=form,
committee_name=committee.display_name)
-async def view(session: web.Committer, name: str) -> response.Response | str:
+async def view(session: web.Committer, name: str) -> web.WerkzeugResponse |
str:
policy_form = None
metadata_form = None
can_edit = False
@@ -450,7 +447,7 @@ async def _policy_form_create(project: sql.Project) ->
ReleasePolicyForm:
return policy_form
-async def _project_add(form: AddForm, session: web.Committer) ->
response.Response:
+async def _project_add(form: AddForm, session: web.Committer) ->
web.WerkzeugResponse:
form_values = await _project_add_validate(form)
if form_values is None:
return quart.redirect(util.as_url(get.projects.add_project,
committee_name=form.committee_name.data))
diff --git a/atr/shared/start.py b/atr/shared/start.py
index f7eccdc..8566444 100644
--- a/atr/shared/start.py
+++ b/atr/shared/start.py
@@ -18,7 +18,6 @@
import asfquart.base as base
import quart
-import werkzeug.wrappers.response as response
import atr.db as db
import atr.db.interaction as interaction
@@ -40,7 +39,7 @@ class StartReleaseForm(forms.Typed):
submit = forms.submit("Start new release")
-async def selected(session: web.Committer, project_name: str) ->
response.Response | str:
+async def selected(session: web.Committer, project_name: str) ->
web.WerkzeugResponse | str:
"""Allow the user to start a new release draft, or handle its
submission."""
await session.check_access(project_name)
diff --git a/atr/shared/tokens.py b/atr/shared/tokens.py
index 9525adc..7be60ae 100644
--- a/atr/shared/tokens.py
+++ b/atr/shared/tokens.py
@@ -26,7 +26,6 @@ import markupsafe
import quart
import sqlmodel
import werkzeug.datastructures as datastructures
-import werkzeug.wrappers.response as response
import wtforms.fields.core as core
import atr.db as db
@@ -62,7 +61,7 @@ class IssueJWTForm(forms.Typed):
submit = forms.submit("Generate JWT")
-async def tokens(session: web.Committer) -> str | response.Response:
+async def tokens(session: web.Committer) -> str | web.WerkzeugResponse:
request_form = await quart.request.form
if is_post := quart.request.method == "POST":
@@ -230,7 +229,7 @@ async def _delete_token(data: db.Session, uid: str,
token_id: int) -> None:
await data.delete(pat)
-async def _handle_post(session: web.Committer, request_form:
datastructures.MultiDict) -> response.Response | None:
+async def _handle_post(session: web.Committer, request_form:
datastructures.MultiDict) -> web.WerkzeugResponse | None:
if "token_id" in request_form:
return await _handle_delete_token_post(session, request_form)
@@ -242,7 +241,7 @@ async def _handle_post(session: web.Committer,
request_form: datastructures.Mult
async def _handle_add_token_post(
session: web.Committer, request_form: datastructures.MultiDict
-) -> response.Response | None:
+) -> web.WerkzeugResponse | None:
add_form = await AddTokenForm.create_form(data=request_form)
if await add_form.validate_on_submit():
label_val = str(add_form.label.data) if add_form.label.data else None
@@ -263,7 +262,7 @@ async def _handle_add_token_post(
async def _handle_delete_token_post(
session: web.Committer, request_form: datastructures.MultiDict
-) -> response.Response | None:
+) -> web.WerkzeugResponse | None:
del_form = await DeleteTokenForm.create_form(data=request_form)
if await del_form.validate_on_submit():
token_id_val = int(str(del_form.token_id.data))
@@ -277,7 +276,7 @@ async def _handle_delete_token_post(
async def _handle_issue_jwt_post(
session: web.Committer, request_form: datastructures.MultiDict
-) -> response.Response | None:
+) -> web.WerkzeugResponse | None:
issue_form = await IssueJWTForm.create_form(data=request_form)
if await issue_form.validate_on_submit():
jwt_token = jwtoken.issue(session.uid)
diff --git a/atr/shared/upload.py b/atr/shared/upload.py
index 0321898..75bfaa9 100644
--- a/atr/shared/upload.py
+++ b/atr/shared/upload.py
@@ -18,7 +18,6 @@
import pathlib
import quart
-import werkzeug.wrappers.response as response
import wtforms
import atr.db as db
@@ -61,7 +60,7 @@ class SvnImportForm(forms.Typed):
submit = forms.submit("Queue SVN import task")
-async def selected(session: web.Committer, project_name: str, version_name:
str) -> response.Response | str:
+async def selected(session: web.Committer, project_name: str, version_name:
str) -> web.WerkzeugResponse | str:
"""Show a page to allow the user to add files to a candidate draft."""
await session.check_access(project_name)
diff --git a/atr/shared/voting.py b/atr/shared/voting.py
index f0057ac..4a25a64 100644
--- a/atr/shared/voting.py
+++ b/atr/shared/voting.py
@@ -20,7 +20,6 @@ import aiofiles.os
import asfquart.base as base
import quart
import quart_wtf.typing as typing
-import werkzeug.wrappers.response as response
import atr.construct as construct
import atr.db as db
@@ -56,7 +55,7 @@ class VoteInitiateForm(forms.Typed):
async def selected_revision(
session: web.Committer, project_name: str, version_name: str, revision: str
-) -> response.Response | str:
+) -> web.WerkzeugResponse | str:
"""Show the vote initiation form for a release."""
await session.check_access(project_name)
@@ -114,7 +113,7 @@ async def start_vote_manual(
selected_revision_number: str,
session: web.Committer,
_data: db.Session,
-) -> response.Response | str:
+) -> web.WerkzeugResponse | str:
async with storage.write(session) as write:
wacp = await
write.as_project_committee_participant(release.project_name)
# This verifies the state and sets the phase to RELEASE_CANDIDATE
@@ -196,7 +195,7 @@ async def _selected_revision_data(
revision: str,
data: db.Session,
session: web.Committer,
-) -> response.Response | str | VoteInitiateForm:
+) -> web.WerkzeugResponse | str | VoteInitiateForm:
committee = release.committee
if committee is None:
raise base.ASFQuartException("Release has no associated committee",
errorcode=400)
diff --git a/atr/web.py b/atr/web.py
index 05f05cb..a843fde 100644
--- a/atr/web.py
+++ b/atr/web.py
@@ -40,6 +40,10 @@ if TYPE_CHECKING:
R = TypeVar("R", covariant=True)
+type WerkzeugResponse = response.Response
+type QuartResponse = quart.Response
+type Response = WerkzeugResponse | QuartResponse
+
class CommitterRouteFunction(Protocol[R]):
"""Protocol for @committer_get decorated functions."""
@@ -108,7 +112,7 @@ class Committer:
async def redirect(
self, route: CommitterRouteFunction[R], success: str | None = None,
error: str | None = None, **kwargs: Any
- ) -> response.Response:
+ ) -> WerkzeugResponse:
"""Redirect to a route with a success or error message."""
return await redirect(route, success, error, **kwargs)
@@ -239,7 +243,7 @@ class ZipResponse(quart.Response):
async def redirect[R](
route: RouteFunction[R], success: str | None = None, error: str | None =
None, **kwargs: Any
-) -> response.Response:
+) -> WerkzeugResponse:
"""Redirect to a route with a success or error message."""
if success is not None:
await quart.flash(success, "success")
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]