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 7bbcf5c Move tokens and upload routes to the new layout
7bbcf5c is described below
commit 7bbcf5c7743803cd6f3ab8fcf9bc99e28266933b
Author: Sean B. Palmer <[email protected]>
AuthorDate: Tue Oct 28 16:26:14 2025 +0000
Move tokens and upload routes to the new layout
---
atr/get/__init__.py | 4 ++
atr/{post/__init__.py => get/tokens.py} | 40 ++++--------------
atr/{post/__init__.py => get/upload.py} | 40 ++++--------------
atr/post/__init__.py | 4 ++
atr/post/draft.py | 27 ++++++------
atr/post/{__init__.py => tokens.py} | 57 ++++++++++----------------
atr/post/{__init__.py => upload.py} | 40 ++++--------------
atr/routes/__init__.py | 4 --
atr/shared/__init__.py | 4 ++
atr/{routes => shared}/tokens.py | 25 ++++-------
atr/{routes => shared}/upload.py | 5 +--
atr/templates/check-selected-release-info.html | 2 +-
atr/templates/includes/sidebar.html | 2 +-
13 files changed, 82 insertions(+), 172 deletions(-)
diff --git a/atr/get/__init__.py b/atr/get/__init__.py
index 53a0ddd..2340899 100644
--- a/atr/get/__init__.py
+++ b/atr/get/__init__.py
@@ -42,6 +42,8 @@ import atr.get.revisions as revisions
import atr.get.root as root
import atr.get.sbom as sbom
import atr.get.start as start
+import atr.get.tokens as tokens
+import atr.get.upload as upload
import atr.get.vote as vote
ROUTES_MODULE: Final[Literal[True]] = True
@@ -70,5 +72,7 @@ __all__ = [
"root",
"sbom",
"start",
+ "tokens",
+ "upload",
"vote",
]
diff --git a/atr/post/__init__.py b/atr/get/tokens.py
similarity index 50%
copy from atr/post/__init__.py
copy to atr/get/tokens.py
index e3ce6cf..8425c0c 100644
--- a/atr/post/__init__.py
+++ b/atr/get/tokens.py
@@ -15,38 +15,14 @@
# specific language governing permissions and limitations
# under the License.
-from typing import Final, Literal
-import atr.post.announce as announce
-import atr.post.candidate as candidate
-import atr.post.distribution as distribution
-import atr.post.draft as draft
-import atr.post.finish as finish
-import atr.post.ignores as ignores
-import atr.post.keys as keys
-import atr.post.preview as preview
-import atr.post.projects as projects
-import atr.post.resolve as resolve
-import atr.post.revisions as revisions
-import atr.post.sbom as sbom
-import atr.post.start as start
-import atr.post.vote as vote
+import werkzeug.wrappers.response as response
-ROUTES_MODULE: Final[Literal[True]] = True
+import atr.blueprints.get as get
+import atr.shared as shared
+import atr.web as web
-__all__ = [
- "announce",
- "candidate",
- "distribution",
- "draft",
- "finish",
- "ignores",
- "keys",
- "preview",
- "projects",
- "resolve",
- "revisions",
- "sbom",
- "start",
- "vote",
-]
+
[email protected]("/tokens")
+async def tokens(session: web.Committer) -> str | response.Response:
+ return await shared.tokens.tokens(session)
diff --git a/atr/post/__init__.py b/atr/get/upload.py
similarity index 50%
copy from atr/post/__init__.py
copy to atr/get/upload.py
index e3ce6cf..d4ce256 100644
--- a/atr/post/__init__.py
+++ b/atr/get/upload.py
@@ -15,38 +15,14 @@
# specific language governing permissions and limitations
# under the License.
-from typing import Final, Literal
-import atr.post.announce as announce
-import atr.post.candidate as candidate
-import atr.post.distribution as distribution
-import atr.post.draft as draft
-import atr.post.finish as finish
-import atr.post.ignores as ignores
-import atr.post.keys as keys
-import atr.post.preview as preview
-import atr.post.projects as projects
-import atr.post.resolve as resolve
-import atr.post.revisions as revisions
-import atr.post.sbom as sbom
-import atr.post.start as start
-import atr.post.vote as vote
+import werkzeug.wrappers.response as response
-ROUTES_MODULE: Final[Literal[True]] = True
+import atr.blueprints.get as get
+import atr.shared as shared
+import atr.web as web
-__all__ = [
- "announce",
- "candidate",
- "distribution",
- "draft",
- "finish",
- "ignores",
- "keys",
- "preview",
- "projects",
- "resolve",
- "revisions",
- "sbom",
- "start",
- "vote",
-]
+
[email protected]("/upload/<project_name>/<version_name>")
+async def selected(session: web.Committer, project_name: str, version_name:
str) -> response.Response | str:
+ return await shared.upload.selected(session, project_name, version_name)
diff --git a/atr/post/__init__.py b/atr/post/__init__.py
index e3ce6cf..7e5238d 100644
--- a/atr/post/__init__.py
+++ b/atr/post/__init__.py
@@ -30,6 +30,8 @@ import atr.post.resolve as resolve
import atr.post.revisions as revisions
import atr.post.sbom as sbom
import atr.post.start as start
+import atr.post.tokens as tokens
+import atr.post.upload as upload
import atr.post.vote as vote
ROUTES_MODULE: Final[Literal[True]] = True
@@ -48,5 +50,7 @@ __all__ = [
"revisions",
"sbom",
"start",
+ "tokens",
+ "upload",
"vote",
]
diff --git a/atr/post/draft.py b/atr/post/draft.py
index 11830e3..e54da85 100644
--- a/atr/post/draft.py
+++ b/atr/post/draft.py
@@ -28,7 +28,7 @@ import quart
import atr.blueprints.post as post
import atr.construct as construct
import atr.forms as forms
-import atr.get.compose as compose
+import atr.get as get
import atr.log as log
import atr.models.sql as sql
import atr.shared as shared
@@ -105,7 +105,7 @@ async def delete_file(session: web.Committer, project_name:
str, version_name: s
for key, value in form.errors.items():
error_summary.append(f"{key}: {value}")
await quart.flash("; ".join(error_summary), "error")
- return await session.redirect(compose.selected,
project_name=project_name, version_name=version_name)
+ return await session.redirect(get.compose.selected,
project_name=project_name, version_name=version_name)
rel_path_to_delete = pathlib.Path(str(form.file_path.data))
@@ -116,7 +116,7 @@ async def delete_file(session: web.Committer, project_name:
str, version_name: s
except Exception as e:
log.exception("Error deleting file:")
await quart.flash(f"Error deleting file: {e!s}", "error")
- return await session.redirect(compose.selected,
project_name=project_name, version_name=version_name)
+ return await session.redirect(get.compose.selected,
project_name=project_name, version_name=version_name)
success_message = f"File '{rel_path_to_delete.name}' deleted successfully"
if metadata_files_deleted:
@@ -125,7 +125,7 @@ async def delete_file(session: web.Committer, project_name:
str, version_name: s
f"file{'' if metadata_files_deleted == 1 else 's'} deleted"
)
return await session.redirect(
- compose.selected, success=success_message, project_name=project_name,
version_name=version_name
+ get.compose.selected, success=success_message,
project_name=project_name, version_name=version_name
)
@@ -148,7 +148,7 @@ async def fresh(session: web.Committer, project_name: str,
version_name: str) ->
pass
return await session.redirect(
- compose.selected,
+ get.compose.selected,
project_name=project_name,
version_name=version_name,
success="All checks restarted",
@@ -178,10 +178,10 @@ async def hashgen(session: web.Committer, project_name:
str, version_name: str,
except Exception as e:
log.exception("Error generating hash file:")
await quart.flash(f"Error generating hash file: {e!s}", "error")
- return await session.redirect(compose.selected,
project_name=project_name, version_name=version_name)
+ return await session.redirect(get.compose.selected,
project_name=project_name, version_name=version_name)
return await session.redirect(
- compose.selected,
+ get.compose.selected,
success=f"{hash_type} file generated successfully",
project_name=project_name,
version_name=version_name,
@@ -235,10 +235,10 @@ async def sbomgen(session: web.Committer, project_name:
str, version_name: str,
except Exception as e:
log.exception("Error generating SBOM:")
await quart.flash(f"Error generating SBOM: {e!s}", "error")
- return await session.redirect(compose.selected,
project_name=project_name, version_name=version_name)
+ return await session.redirect(get.compose.selected,
project_name=project_name, version_name=version_name)
return await session.redirect(
- compose.selected,
+ get.compose.selected,
success=f"SBOM generation task queued for {rel_path.name}",
project_name=project_name,
version_name=version_name,
@@ -248,17 +248,16 @@ 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:
"""Import files from SVN into a draft."""
- import atr.routes.upload as upload
await session.check_access(project_name)
- form = await upload.SvnImportForm.create_form()
+ form = await shared.upload.SvnImportForm.create_form()
if not await form.validate_on_submit():
for _field, errors in form.errors.items():
for error in errors:
await quart.flash(f"{error}", "error")
return await session.redirect(
- upload.selected,
+ get.upload.selected,
project_name=project_name,
version_name=version_name,
)
@@ -277,14 +276,14 @@ async def svnload(session: web.Committer, project_name:
str, version_name: str)
except Exception:
log.exception("Error queueing SVN import task:")
return await session.redirect(
- upload.selected,
+ get.upload.selected,
error="Error queueing SVN import task",
project_name=project_name,
version_name=version_name,
)
return await session.redirect(
- compose.selected,
+ get.compose.selected,
success="SVN import task queued successfully",
project_name=project_name,
version_name=version_name,
diff --git a/atr/post/__init__.py b/atr/post/tokens.py
similarity index 50%
copy from atr/post/__init__.py
copy to atr/post/tokens.py
index e3ce6cf..9482bf6 100644
--- a/atr/post/__init__.py
+++ b/atr/post/tokens.py
@@ -15,38 +15,25 @@
# specific language governing permissions and limitations
# under the License.
-from typing import Final, Literal
-
-import atr.post.announce as announce
-import atr.post.candidate as candidate
-import atr.post.distribution as distribution
-import atr.post.draft as draft
-import atr.post.finish as finish
-import atr.post.ignores as ignores
-import atr.post.keys as keys
-import atr.post.preview as preview
-import atr.post.projects as projects
-import atr.post.resolve as resolve
-import atr.post.revisions as revisions
-import atr.post.sbom as sbom
-import atr.post.start as start
-import atr.post.vote as vote
-
-ROUTES_MODULE: Final[Literal[True]] = True
-
-__all__ = [
- "announce",
- "candidate",
- "distribution",
- "draft",
- "finish",
- "ignores",
- "keys",
- "preview",
- "projects",
- "resolve",
- "revisions",
- "sbom",
- "start",
- "vote",
-]
+
+import quart
+import werkzeug.wrappers.response as response
+
+import atr.blueprints.post as post
+import atr.jwtoken as jwtoken
+import atr.shared as shared
+import atr.util as util
+import atr.web as web
+
+
[email protected]("/tokens/jwt")
+async def jwt_post(session: web.Committer) -> quart.Response:
+ await util.validate_empty_form()
+
+ jwt_token = jwtoken.issue(session.uid)
+ return web.TextResponse(jwt_token)
+
+
[email protected]("/tokens")
+async def tokens(session: web.Committer) -> str | response.Response:
+ return await shared.tokens.tokens(session)
diff --git a/atr/post/__init__.py b/atr/post/upload.py
similarity index 50%
copy from atr/post/__init__.py
copy to atr/post/upload.py
index e3ce6cf..0d14c9b 100644
--- a/atr/post/__init__.py
+++ b/atr/post/upload.py
@@ -15,38 +15,14 @@
# specific language governing permissions and limitations
# under the License.
-from typing import Final, Literal
-import atr.post.announce as announce
-import atr.post.candidate as candidate
-import atr.post.distribution as distribution
-import atr.post.draft as draft
-import atr.post.finish as finish
-import atr.post.ignores as ignores
-import atr.post.keys as keys
-import atr.post.preview as preview
-import atr.post.projects as projects
-import atr.post.resolve as resolve
-import atr.post.revisions as revisions
-import atr.post.sbom as sbom
-import atr.post.start as start
-import atr.post.vote as vote
+import werkzeug.wrappers.response as response
-ROUTES_MODULE: Final[Literal[True]] = True
+import atr.blueprints.post as post
+import atr.shared as shared
+import atr.web as web
-__all__ = [
- "announce",
- "candidate",
- "distribution",
- "draft",
- "finish",
- "ignores",
- "keys",
- "preview",
- "projects",
- "resolve",
- "revisions",
- "sbom",
- "start",
- "vote",
-]
+
[email protected]("/upload/<project_name>/<version_name>")
+async def selected(session: web.Committer, project_name: str, version_name:
str) -> response.Response | str:
+ return await shared.upload.selected(session, project_name, version_name)
diff --git a/atr/routes/__init__.py b/atr/routes/__init__.py
index 30b164b..a8e1b85 100644
--- a/atr/routes/__init__.py
+++ b/atr/routes/__init__.py
@@ -15,14 +15,10 @@
# specific language governing permissions and limitations
# under the License.
-import atr.routes.tokens as tokens
-import atr.routes.upload as upload
import atr.routes.user as user
import atr.routes.voting as voting
__all__ = [
- "tokens",
- "upload",
"user",
"voting",
]
diff --git a/atr/shared/__init__.py b/atr/shared/__init__.py
index 822ed7c..d7c5835 100644
--- a/atr/shared/__init__.py
+++ b/atr/shared/__init__.py
@@ -34,6 +34,8 @@ import atr.shared.keys as keys
import atr.shared.projects as projects
import atr.shared.resolve as resolve
import atr.shared.start as start
+import atr.shared.tokens as tokens
+import atr.shared.upload as upload
import atr.shared.vote as vote
import atr.storage as storage
import atr.template as template
@@ -190,5 +192,7 @@ __all__ = [
"projects",
"resolve",
"start",
+ "tokens",
+ "upload",
"vote",
]
diff --git a/atr/routes/tokens.py b/atr/shared/tokens.py
similarity index 92%
rename from atr/routes/tokens.py
rename to atr/shared/tokens.py
index 55f2ca0..97c5b0f 100644
--- a/atr/routes/tokens.py
+++ b/atr/shared/tokens.py
@@ -35,7 +35,7 @@ import atr.htm as htm
import atr.jwtoken as jwtoken
import atr.log as log
import atr.models.sql as sql
-import atr.route as route
+import atr.post as post
import atr.storage as storage
import atr.template as templates
import atr.util as util
@@ -61,16 +61,7 @@ class IssueJWTForm(forms.Typed):
submit = forms.submit("Generate JWT")
[email protected]("/tokens/jwt", methods=["POST"])
-async def jwt_post(session: route.CommitterSession) -> quart.Response:
- await util.validate_empty_form()
-
- jwt_token = jwtoken.issue(session.uid)
- return web.TextResponse(jwt_token)
-
-
[email protected]("/tokens", methods=["GET", "POST"])
-async def tokens(session: route.CommitterSession) -> str | response.Response:
+async def tokens(session: web.Committer) -> str | response.Response:
request_form = await quart.request.form
if is_post := quart.request.method == "POST":
@@ -177,7 +168,7 @@ def _build_delete_form_element(token_id: int | None) ->
markupsafe.Markup:
def _build_issue_jwt_form_element(j_form: IssueJWTForm) -> markupsafe.Markup:
- elem = htm.form("#issue-jwt-form", method="post",
action=util.as_url(jwt_post))[
+ elem = htm.form("#issue-jwt-form", method="post",
action=util.as_url(post.tokens.jwt_post))[
_as_markup(j_form.csrf_token),
j_form.submit(class_="btn btn-primary"),
]
@@ -238,9 +229,7 @@ async def _delete_token(data: db.Session, uid: str,
token_id: int) -> None:
await data.delete(pat)
-async def _handle_post(
- session: route.CommitterSession, request_form: datastructures.MultiDict
-) -> response.Response | None:
+async def _handle_post(session: web.Committer, request_form:
datastructures.MultiDict) -> response.Response | None:
if "token_id" in request_form:
return await _handle_delete_token_post(session, request_form)
@@ -251,7 +240,7 @@ async def _handle_post(
async def _handle_add_token_post(
- session: route.CommitterSession, request_form: datastructures.MultiDict
+ session: web.Committer, request_form: datastructures.MultiDict
) -> response.Response | None:
add_form = await AddTokenForm.create_form(data=request_form)
if await add_form.validate_on_submit():
@@ -272,7 +261,7 @@ async def _handle_add_token_post(
async def _handle_delete_token_post(
- session: route.CommitterSession, request_form: datastructures.MultiDict
+ session: web.Committer, request_form: datastructures.MultiDict
) -> response.Response | None:
del_form = await DeleteTokenForm.create_form(data=request_form)
if await del_form.validate_on_submit():
@@ -286,7 +275,7 @@ async def _handle_delete_token_post(
async def _handle_issue_jwt_post(
- session: route.CommitterSession, request_form: datastructures.MultiDict
+ session: web.Committer, request_form: datastructures.MultiDict
) -> response.Response | None:
issue_form = await IssueJWTForm.create_form(data=request_form)
if await issue_form.validate_on_submit():
diff --git a/atr/routes/upload.py b/atr/shared/upload.py
similarity index 94%
rename from atr/routes/upload.py
rename to atr/shared/upload.py
index e8fa43a..f554f46 100644
--- a/atr/routes/upload.py
+++ b/atr/shared/upload.py
@@ -25,9 +25,9 @@ import atr.db as db
import atr.forms as forms
import atr.get.compose as compose
import atr.log as log
-import atr.route as route
import atr.storage as storage
import atr.template as template
+import atr.web as web
class AddFilesForm(forms.Typed):
@@ -61,8 +61,7 @@ class SvnImportForm(forms.Typed):
submit = forms.submit("Queue SVN import task")
[email protected]("/upload/<project_name>/<version_name>", methods=["GET",
"POST"])
-async def selected(session: route.CommitterSession, project_name: str,
version_name: str) -> response.Response | str:
+async def selected(session: web.Committer, project_name: str, version_name:
str) -> response.Response | 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/templates/check-selected-release-info.html
b/atr/templates/check-selected-release-info.html
index 2b055bd..65efe3b 100644
--- a/atr/templates/check-selected-release-info.html
+++ b/atr/templates/check-selected-release-info.html
@@ -41,7 +41,7 @@
</div>
<div class="d-flex flex-wrap gap-2">
{% if phase == "release_candidate_draft" %}
- <a href="{{ as_url(routes.upload.selected,
project_name=release.project.name, version_name=release.version) }}"
+ <a href="{{ as_url(get.upload.selected,
project_name=release.project.name, version_name=release.version) }}"
title="Upload files to this draft"
class="btn btn-primary"><i class="bi bi-upload me-1"></i> Upload
files</a>
diff --git a/atr/templates/includes/sidebar.html
b/atr/templates/includes/sidebar.html
index c9f860d..9d1d6d7 100644
--- a/atr/templates/includes/sidebar.html
+++ b/atr/templates/includes/sidebar.html
@@ -109,7 +109,7 @@
</li>
<li>
<i class="bi bi-key"></i>
- <a href="{{ as_url(routes.tokens.tokens) }}">API tokens</a>
+ <a href="{{ as_url(get.tokens.tokens) }}">API tokens</a>
</li>
</ul>
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]