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]

Reply via email to