dave2wave commented on issue #242:
URL: 
https://github.com/apache/tooling-trusted-releases/issues/242#issuecomment-3740716105

   This discussion is rambling all over. 
   
   Let's focus on a review of endpoints
   
   ```
   atr % grep -rni -A 1 "@post" > /tmp/atr-post.txt
   atr % grep -rni -A 1 "@get" > /tmp/atr-get.txt  
   ```
   
   ```
   ./blueprints/post.py:79:    # @post.form(form.Empty)
   ./blueprints/post.py-80-    # async def test_empty(
   --
   ./blueprints/post.py:88:    # @post.empty()
   ./blueprints/post.py-89-    # async def test_empty(
   --
   ./post/user.py:27:@post.committer("/user/cache")
   ./post/user.py:28:@post.form(shared.user.UserCacheForm)
   ./post/user.py-29-async def session_post(session: web.Committer, 
user_cache_form: shared.user.UserCacheForm) -> web.WerkzeugResponse:
   --
   
./post/resolve.py:33:@post.committer("/resolve/<project_name>/<version_name>")
   ./post/resolve.py:34:@post.form(shared.resolve.ResolveForm)
   ./post/resolve.py-35-async def selected(
   --
   
./post/upload.py:42:@post.committer("/upload/finalise/<project_name>/<version_name>/<upload_session>")
   ./post/upload.py-43-async def finalise(
   --
   ./post/upload.py:90:@post.committer("/upload/<project_name>/<version_name>")
   ./post/upload.py:91:@post.form(shared.upload.UploadForm)
   ./post/upload.py-92-async def selected(
   --
   
./post/upload.py:105:@post.committer("/upload/stage/<project_name>/<version_name>/<upload_session>")
   ./post/upload.py-106-async def stage(
   --
   ./post/ignores.py:26:@post.committer("/ignores/<committee_name>")
   ./post/ignores.py:27:@post.form(shared.ignores.IgnoreForm)
   ./post/ignores.py-28-async def ignores(
   --
   
./post/revisions.py:31:@post.committer("/revisions/<project_name>/<version_name>")
   ./post/revisions.py:32:@post.form(shared.revisions.RevisionForm)
   ./post/revisions.py-33-async def selected_post(
   --
   ./post/keys.py:42:@post.committer("/keys/add")
   ./post/keys.py:43:@post.form(shared.keys.AddOpenPGPKeyForm)
   ./post/keys.py-44-async def add(session: web.Committer, 
add_openpgp_key_form: shared.keys.AddOpenPGPKeyForm) -> web.WerkzeugResponse:
   --
   ./post/keys.py:84:@post.committer("/keys/details/<fingerprint>")
   ./post/keys.py:85:@post.form(shared.keys.UpdateKeyCommitteesForm)
   ./post/keys.py-86-async def details(
   --
   
./post/keys.py:128:@post.committer("/keys/import/<project_name>/<version_name>")
   ./post/keys.py:129:@post.empty()
   ./post/keys.py-130-async def import_selected_revision(
   --
   ./post/keys.py:148:@post.committer("/keys")
   ./post/keys.py:149:@post.form(shared.keys.KeysForm)
   ./post/keys.py-150-async def keys(session: web.Committer, keys_form: 
shared.keys.KeysForm) -> web.WerkzeugResponse:
   --
   ./post/keys.py:163:@post.committer("/keys/ssh/add")
   ./post/keys.py:164:@post.form(shared.keys.AddSSHKeyForm)
   ./post/keys.py-165-async def ssh_add(session: web.Committer, 
add_ssh_key_form: shared.keys.AddSSHKeyForm) -> web.WerkzeugResponse:
   --
   ./post/keys.py:182:@post.committer("/keys/upload")
   ./post/keys.py:183:@post.form(shared.keys.UploadKeysForm)
   ./post/keys.py-184-async def upload(session: web.Committer, upload_form: 
shared.keys.UploadKeysForm) -> str:
   --
   ./post/tokens.py:36:@post.committer("/tokens/jwt")
   ./post/tokens.py:37:@post.empty()
   ./post/tokens.py-38-async def jwt_post(session: web.Committer) -> 
web.QuartResponse:
   --
   ./post/tokens.py:43:@post.committer("/tokens")
   ./post/tokens.py:44:@post.form(shared.tokens.TokenForm)
   ./post/tokens.py-45-async def tokens(session: web.Committer, token_form: 
shared.tokens.TokenForm) -> web.WerkzeugResponse:
   --
   ./post/test.py:27:@post.public("/test/empty")
   ./post/test.py:28:@post.empty()
   ./post/test.py-29-async def test_empty(session: web.Committer | None) -> 
web.WerkzeugResponse:
   --
   ./post/test.py:36:@post.public("/test/multiple")
   ./post/test.py:37:@post.form(shared.test.MultipleForm)
   ./post/test.py-38-async def test_multiple(session: web.Committer | None, 
form: shared.test.MultipleForm) -> web.WerkzeugResponse:
   --
   ./post/test.py:53:@post.public("/test/single")
   ./post/test.py:54:@post.form(shared.test.SingleForm)
   ./post/test.py-55-async def test_single(session: web.Committer | None, form: 
shared.test.SingleForm) -> web.WerkzeugResponse:
   --
   
./post/manual.py:29:@post.committer("/manual/resolve/<project_name>/<version_name>")
   ./post/manual.py:30:@post.form(shared.manual.ResolveVoteForm)
   ./post/manual.py-31-async def resolve_selected(
   --
   
./post/manual.py:75:@post.committer("/manual/start/<project_name>/<version_name>/<revision>")
   ./post/manual.py:76:@post.empty()
   ./post/manual.py-77-async def start_selected_revision(
   --
   ./post/start.py:28:@post.committer("/start/<project_name>")
   ./post/start.py:29:@post.form(shared.start.StartReleaseForm)
   ./post/start.py-30-async def selected(
   --
   
./post/distribution.py:29:@post.committer("/distribution/delete/<project>/<version>")
   ./post/distribution.py:30:@post.form(shared.distribution.DeleteForm)
   ./post/distribution.py-31-async def delete(
   --
   
./post/distribution.py:110:@post.committer("/distribution/record/<project>/<version>")
   ./post/distribution.py:111:@post.form(shared.distribution.DistributeForm)
   ./post/distribution.py-112-async def record_selected(
   --
   
./post/distribution.py:118:@post.committer("/distribution/stage/<project>/<version>")
   ./post/distribution.py:119:@post.form(shared.distribution.DistributeForm)
   ./post/distribution.py-120-async def stage_selected(
   --
   
./post/sbom.py:39:@post.committer("/sbom/report/<project>/<version>/<path:file_path>")
   ./post/sbom.py:40:@post.form(shared.sbom.SBOMForm)
   ./post/sbom.py-41-async def report(
   --
   ./post/vote.py:28:@post.committer("/vote/<project_name>/<version_name>")
   ./post/vote.py:29:@post.form(shared.vote.CastVoteForm)
   ./post/vote.py-30-async def selected_post(
   --
   
./post/voting.py:37:@post.committer("/voting/body/preview/<project_name>/<version_name>/<revision_number>")
   ./post/voting.py:38:@post.form(BodyPreviewForm)
   ./post/voting.py-39-async def body_preview(
   --
   
./post/voting.py:64:@post.committer("/voting/<project_name>/<version_name>/<revision>")
   ./post/voting.py:65:@post.form(shared.voting.StartVotingForm)
   ./post/voting.py-66-async def selected_revision(
   --
   
./post/announce.py:31:@post.committer("/announce/<project_name>/<version_name>")
   ./post/announce.py:32:@post.form(shared.announce.AnnounceForm)
   ./post/announce.py-33-async def selected(
   --
   ./post/projects.py:32:@post.committer("/project/add/<committee_name>")
   ./post/projects.py:33:@post.form(shared.projects.AddProjectForm)
   ./post/projects.py-34-async def add_project(
   --
   ./post/projects.py:54:@post.committer("/project/delete")
   ./post/projects.py:55:@post.form(shared.projects.DeleteSelectedProject)
   ./post/projects.py-56-async def delete(
   --
   ./post/projects.py:74:@post.committer("/projects/<name>")
   ./post/projects.py:75:@post.form(shared.projects.ProjectViewForm)
   ./post/projects.py-76-async def view(
   --
   ./post/draft.py:37:@post.committer("/compose/<project_name>/<version_name>")
   ./post/draft.py:38:@post.empty()
   ./post/draft.py-39-async def delete(session: web.Committer, project_name: 
str, version_name: str) -> web.WerkzeugResponse:
   --
   
./post/draft.py:64:@post.committer("/draft/delete-file/<project_name>/<version_name>")
   ./post/draft.py:65:@post.form(shared.draft.DeleteFileForm)
   ./post/draft.py-66-async def delete_file(
   --
   
./post/draft.py:94:@post.committer("/draft/fresh/<project_name>/<version_name>")
   ./post/draft.py:95:@post.empty()
   ./post/draft.py-96-async def fresh(session: web.Committer, project_name: 
str, version_name: str) -> web.WerkzeugResponse:
   --
   
./post/draft.py:120:@post.committer("/draft/hashgen/<project_name>/<version_name>/<path:file_path>")
   ./post/draft.py:121:@post.empty()
   ./post/draft.py-122-async def hashgen(session: web.Committer, project_name: 
str, version_name: str, file_path: str) -> web.WerkzeugResponse:
   --
   
./post/draft.py:149:@post.committer("/draft/sbomgen/<project_name>/<version_name>/<path:file_path>")
   ./post/draft.py:150:@post.empty()
   ./post/draft.py-151-async def sbomgen(session: web.Committer, project_name: 
str, version_name: str, file_path: str) -> web.WerkzeugResponse:
   --
   ./post/finish.py:28:@post.committer("/finish/<project_name>/<version_name>")
   ./post/finish.py:29:@post.form(shared.finish.FinishForm)
   ./post/finish.py-30-async def selected(
   --
   ./docs/user-interface.md:124:To use a form in a route, use the 
[`@post.committer()`](/ref/atr/blueprints/post.py:committer) decorator to get 
the session and auth the user, and the 
[`@post.form()`](/ref/atr/blueprints/post.py:form) decorator to parse and 
validate input data:
   ./docs/user-interface.md-125-
   --
   ./docs/user-interface.md:127:@post.committer("/keys/add")
   ./docs/user-interface.md:128:@post.form(shared.keys.AddOpenPGPKeyForm)
   ./docs/user-interface.md-129-async def add(session: web.Committer, 
add_openpgp_key_form: shared.keys.AddOpenPGPKeyForm) -> web.WerkzeugResponse:
   --
   ./docs/user-interface.md:226:A typical route that renders UI first 
authenticates the user, loads data from the database, builds HTML using htpy, 
and renders it using a template. GET and POST requests are handled by separate 
routes, with form validation automatically handled by the 
[`@post.form()`](/ref/atr/blueprints/post.py:form) decorator. Here is a 
simplified example from [`get/keys.py`](/ref/atr/get/keys.py:add):
   ./docs/user-interface.md-227-
   --
   ./docs/user-interface.md:271:@post.committer("/keys/add")
   ./docs/user-interface.md:272:@post.form(shared.keys.AddOpenPGPKeyForm)
   ./docs/user-interface.md-273-async def add(session: web.Committer, 
add_openpgp_key_form: shared.keys.AddOpenPGPKeyForm) -> web.WerkzeugResponse:
   --
   ./docs/user-interface.md:288:The 
[`@post.form()`](/ref/atr/blueprints/post.py:form) decorator handles form 
validation automatically. If validation fails, it flashes error messages and 
redirects back to the GET route. If validation succeeds, the validated form 
instance is injected into the route handler as a parameter.
   ./docs/user-interface.md-289-
   ```
   
   ```
   ./get/checklist.py:34:@get.public("/checklist/<project_name>/<version_name>")
   ./get/checklist.py-35-async def selected(session: web.Committer | None, 
project_name: str, version_name: str) -> str:
   --
   ./get/user.py:27:@get.committer("/user/cache")
   ./get/user.py-28-async def cache_get(session: web.Committer) -> str:
   --
   ./get/release.py:31:@get.public("/releases/finished/<project_name>")
   ./get/release.py-32-async def finished(session: web.Committer | None, 
project_name: str) -> str:
   --
   ./get/release.py:55:@get.public("/releases")
   ./get/release.py-56-async def releases(session: web.Committer | None) -> str:
   --
   ./get/release.py:80:@get.committer("/release/select/<project_name>")
   ./get/release.py-81-async def select(session: web.Committer, project_name: 
str) -> str:
   --
   ./get/upload.py:37:@get.committer("/upload/<project_name>/<version_name>")
   ./get/upload.py-38-async def selected(session: web.Committer, project_name: 
str, version_name: str) -> str:
   --
   ./get/compose.py:28:@get.committer("/compose/<project_name>/<version_name>")
   ./get/compose.py-29-async def selected(session: web.Committer, project_name: 
str, version_name: str) -> web.WerkzeugResponse | str:
   --
   ./get/ignores.py:30:@get.committer("/ignores/<committee_name>")
   ./get/ignores.py-31-async def ignores(session: web.Committer, 
committee_name: str) -> str | web.WerkzeugResponse:
   --
   ./get/checks.py:102:@get.public("/checks/<project_name>/<version_name>")
   ./get/checks.py-103-async def selected(session: web.Committer | None, 
project_name: str, version_name: str) -> str:
   --
   
./get/checks.py:139:@get.committer("/checks/<project_name>/<version_name>/<revision_number>")
   ./get/checks.py-140-async def selected_revision(
   --
   ./get/committees.py:33:@get.public("/committees")
   ./get/committees.py-34-async def directory(session: web.Committer | None) -> 
str:
   --
   ./get/committees.py:46:@get.public("/committees/<name>")
   ./get/committees.py-47-async def view(session: web.Committer | None, name: 
str) -> str:
   --
   
./get/revisions.py:49:@get.committer("/revisions/<project_name>/<version_name>")
   ./get/revisions.py-50-async def selected(session: web.Committer, 
project_name: str, version_name: str) -> str:
   --
   
./get/download.py:39:@get.committer("/download/all/<project_name>/<version_name>")
   ./get/download.py-40-async def all_selected(session: web.Committer, 
project_name: str, version_name: str) -> web.WerkzeugResponse | str:
   --
   
./get/download.py:66:@get.public("/download/path/<project_name>/<version_name>/<path:file_path>")
   ./get/download.py-67-async def path(session: web.Committer | None, 
project_name: str, version_name: str, file_path: str) -> web.Response:
   --
   
./get/download.py:72:@get.public("/download/path/<project_name>/<version_name>/")
   ./get/download.py-73-async def path_empty(session: web.Committer | None, 
project_name: str, version_name: str) -> web.Response:
   --
   
./get/download.py:78:@get.public("/download/sh/<project_name>/<version_name>")
   ./get/download.py-79-async def sh_selected(session: web.Committer | None, 
project_name: str, version_name: str) -> web.Response:
   --
   
./get/download.py:93:@get.public("/download/urls/<project_name>/<version_name>")
   ./get/download.py-94-async def urls_selected(session: web.Committer | None, 
project_name: str, version_name: str) -> web.Response:
   --
   
./get/download.py:108:@get.committer("/download/zip/<project_name>/<version_name>")
   ./get/download.py-109-async def zip_selected(session: web.Committer, 
project_name: str, version_name: str) -> web.Response:
   --
   ./get/docs.py:52:@get.public("/docs/")
   ./get/docs.py-53-async def index(session: web.Committer | None) -> str:
   --
   ./get/docs.py:57:@get.public("/docs/<path:page>")
   ./get/docs.py-58-async def page(session: web.Committer | None, page: str) -> 
str:
   --
   ./get/keys.py:38:@get.committer("/keys/add")
   ./get/keys.py-39-async def add(session: web.Committer) -> str:
   --
   ./get/keys.py:71:@get.committer("/keys/details/<fingerprint>")
   ./get/keys.py-72-async def details(session: web.Committer, fingerprint: str) 
-> str:
   --
   ./get/keys.py:177:@get.committer("/keys/export/<committee_name>")
   ./get/keys.py-178-async def export(session: web.Committer, committee_name: 
str) -> web.TextResponse:
   --
   ./get/keys.py:187:@get.committer("/keys")
   ./get/keys.py-188-async def keys(session: web.Committer) -> str:
   --
   ./get/keys.py:224:@get.committer("/keys/ssh/add")
   ./get/keys.py-225-async def ssh_add(session: web.Committer) -> str:
   --
   ./get/keys.py:253:@get.committer("/keys/upload")
   ./get/keys.py-254-async def upload(session: web.Committer) -> str:
   --
   ./get/tokens.py:30:@get.committer("/tokens")
   ./get/tokens.py-31-async def tokens(session: web.Committer) -> str:
   --
   ./get/test.py:33:@get.public("/test/empty")
   ./get/test.py-34-async def test_empty(session: web.Committer | None) -> str:
   --
   ./get/test.py:50:@get.public("/test/login")
   ./get/test.py-51-async def test_login(session: web.Committer | None) -> 
web.WerkzeugResponse:
   --
   ./get/test.py:70:@get.public("/test/multiple")
   ./get/test.py-71-async def test_multiple(session: web.Committer | None) -> 
str:
   --
   ./get/test.py:94:@get.public("/test/single")
   ./get/test.py-95-async def test_single(session: web.Committer | None) -> str:
   --
   
./get/test.py:122:@get.public("/test/vote/<category>/<project_name>/<version_name>")
   ./get/test.py-123-async def test_vote(session: web.Committer | None, 
category: str, project_name: str, version_name: str) -> str:
   --
   
./get/manual.py:34:@get.committer("/manual/resolve/<project_name>/<version_name>")
   ./get/manual.py-35-async def resolve_selected(session: web.Committer, 
project_name: str, version_name: str) -> str:
   --
   
./get/manual.py:58:@get.committer("/manual/start/<project_name>/<version_name>/<revision>")
   ./get/manual.py-59-async def start_selected_revision(
   --
   ./get/start.py:34:@get.committer("/start/<project_name>")
   ./get/start.py-35-async def selected(session: web.Committer, project_name: 
str) -> str:
   --
   
./get/distribution.py:32:@get.committer("/distributions/list/<project>/<version>")
   ./get/distribution.py-33-async def list_get(session: web.Committer, project: 
str, version: str) -> str:
   --
   
./get/distribution.py:112:@get.committer("/distribution/record/<project>/<version>")
   ./get/distribution.py-113-async def record(session: web.Committer, project: 
str, version: str) -> str:
   --
   
./get/distribution.py:117:@get.committer("/distribution/stage/<project>/<version>")
   ./get/distribution.py-118-async def stage(session: web.Committer, project: 
str, version: str) -> str:
   --
   
./get/sbom.py:47:@get.committer("/sbom/report/<project>/<version>/<path:file_path>")
   ./get/sbom.py-48-async def report(session: web.Committer, project: str, 
version: str, file_path: str) -> str:
   --
   ./get/file.py:35:@get.committer("/file/<project_name>/<version_name>")
   ./get/file.py-36-async def selected(session: web.Committer, project_name: 
str, version_name: str) -> str:
   --
   
./get/file.py:127:@get.committer("/file/<project_name>/<version_name>/<path:file_path>")
   ./get/file.py-128-async def selected_path(session: web.Committer, 
project_name: str, version_name: str, file_path: str) -> str:
   --
   ./get/published.py:32:@get.committer("/published/<path:path>")
   ./get/published.py-33-async def path(session: web.Committer, path: str) -> 
web.QuartResponse:
   --
   ./get/published.py:44:@get.committer("/published/")
   ./get/published.py-45-async def root(session: web.Committer) -> 
web.QuartResponse:
   --
   ./get/ref.py:33:@get.public("/ref/<path:ref_path>")
   ./get/ref.py-34-async def resolve(session: web.Committer | None, ref_path: 
str) -> web.WerkzeugResponse:
   --
   ./get/vote.py:174:@get.public("/vote/<project_name>/<version_name>")
   ./get/vote.py-175-async def selected(session: web.Committer | None, 
project_name: str, version_name: str) -> web.WerkzeugResponse | str:
   --
   
./get/voting.py:40:@get.committer("/voting/<project_name>/<version_name>/<revision>")
   ./get/voting.py-41-async def selected_revision(
   --
   ./get/root.py:61:@get.committer("/about")
   ./get/root.py-62-async def about(session: web.Committer) -> str:
   --
   ./get/root.py:67:@get.public("/")
   ./get/root.py-68-async def index(session: web.Committer | None) -> 
quart_response.Response | str:
   --
   ./get/root.py:142:@get.public("/policies")
   ./get/root.py-143-async def policies(session: web.Committer | None) -> str:
   --
   ./get/root.py:147:@get.public("/miscellaneous/resolved.json")
   ./get/root.py-148-async def resolved_json(session: web.Committer | None) -> 
quart_response.Response:
   --
   ./get/root.py:155:@get.committer("/tutorial")
   ./get/root.py-156-async def tutorial(session: web.Committer) -> str:
   --
   
./get/announce.py:38:@get.committer("/announce/<project_name>/<version_name>")
   ./get/announce.py-39-async def selected(session: web.Committer, 
project_name: str, version_name: str) -> str | web.WerkzeugResponse:
   --
   ./get/projects.py:43:@get.committer("/project/add/<committee_name>")
   ./get/projects.py-44-async def add_project(session: web.Committer, 
committee_name: str) -> web.WerkzeugResponse | str:
   --
   ./get/projects.py:87:@get.public("/projects")
   ./get/projects.py-88-async def projects(session: web.Committer | None) -> 
str:
   --
   ./get/projects.py:109:@get.committer("/project/select")
   ./get/projects.py-110-async def select(session: web.Committer) -> str:
   --
   ./get/projects.py:135:@get.committer("/projects/<name>")
   ./get/projects.py-136-async def view(session: web.Committer, name: str) -> 
web.WerkzeugResponse | str:
   --
   
./get/draft.py:34:@get.committer("/draft/tools/<project_name>/<version_name>/<path:file_path>")
   ./get/draft.py-35-async def tools(session: web.Committer, project_name: str, 
version_name: str, file_path: str) -> str:
   --
   
./get/report.py:32:@get.committer("/report/<project_name>/<version_name>/<path:rel_path>")
   ./get/report.py-33-async def selected_path(session: web.Committer, 
project_name: str, version_name: str, rel_path: str) -> str:
   --
   ./get/finish.py:57:@get.committer("/finish/<project_name>/<version_name>")
   ./get/finish.py-58-async def selected(
   --
   ./docs/user-interface.md:229:@get.committer("/keys/add")
   ./docs/user-interface.md-230-async def add(session: web.Committer) -> str:
   --
   ./docs/user-interface.md:262:The route is decorated with 
[`@get.committer()`](/ref/atr/blueprints/get.py:committer), which handles 
authentication and provides a `session` object that is an instance of 
[`web.Committer`](/ref/atr/web.py:Committer) with a range of useful properties 
and methods.
   ./docs/user-interface.md-263-
   ```
   
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to