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-release.git


The following commit(s) were added to refs/heads/main by this push:
     new d3ad23d  Rename and remove some API endpoints
d3ad23d is described below

commit d3ad23d122b85e860d959ee09e446126a673bf79
Author: Sean B. Palmer <[email protected]>
AuthorDate: Tue Jul 29 14:11:35 2025 +0100

    Rename and remove some API endpoints
---
 atr/blueprints/api/api.py | 140 +++++++++++++++-------------------------------
 atr/models/api.py         |  63 +++++++--------------
 2 files changed, 66 insertions(+), 137 deletions(-)

diff --git a/atr/blueprints/api/api.py b/atr/blueprints/api/api.py
index 93a174c..6e5c005 100644
--- a/atr/blueprints/api/api.py
+++ b/atr/blueprints/api/api.py
@@ -361,39 +361,6 @@ async def jwt_create(data: models.api.JwtCreateArgs) -> 
DictResponse:
     ).model_dump(), 200
 
 
-# TODO: Deprecate this endpoint
[email protected]("/keys")
-@quart_schema.validate_querystring(models.api.KeysQuery)
-@quart_schema.validate_response(models.api.KeysResults, 200)
-async def keys_endpoint(query_args: models.api.KeysQuery) -> DictResponse:
-    """
-    All public OpenPGP keys, with pagination support.
-
-    Warning: this endpoint is deprecated.
-    """
-    # TODO: Rather than pagination, let's support keys by committee and by user
-    # That way, consumers can scroll through committees or users
-    # Which performs logical pagination, rather than arbitrary window 
pagination
-    _pagination_args_validate(query_args)
-    via = sql.validate_instrumented_attribute
-    async with db.session() as data:
-        statement = (
-            sqlmodel.select(sql.PublicSigningKey)
-            .limit(query_args.limit)
-            .offset(query_args.offset)
-            .order_by(via(sql.PublicSigningKey.fingerprint).asc())
-        )
-        paged_keys = (await data.execute(statement)).scalars().all()
-        count = (
-            await 
data.execute(sqlalchemy.select(sqlalchemy.func.count(via(sql.PublicSigningKey.fingerprint))))
-        ).scalar_one()
-    return models.api.KeysResults(
-        endpoint="/keys",
-        data=paged_keys,
-        count=count,
-    ).model_dump(), 200
-
-
 @api.BLUEPRINT.route("/keys/add", methods=["POST"])
 @jwtoken.require
 @quart_schema.security_scheme([{"BearerAuth": []}])
@@ -461,22 +428,6 @@ async def keys_delete(data: models.api.KeysDeleteArgs) -> 
DictResponse:
     ).model_dump(), 200
 
 
-# @api.BLUEPRINT.route("/keys/committee/<committee>")
-# @quart_schema.validate_response(models.api.KeysUserResults, 200)
-# async def keys_committee(committee: str) -> DictResponse:
-#     """Return all public signing keys for a specific committee."""
-#     _simple_check(committee)
-#     async with db.session() as data:
-#         committee_object = await data.committee(
-#             name=committee, _public_signing_keys=True
-#         ).demand(exceptions.NotFound(f"Committee '{committee}' was not 
found"))
-#         keys = committee_object.public_signing_keys
-#     return models.api.KeysCommitteeResults(
-#         endpoint="/keys/committee",
-#         keys=keys,
-#     ).model_dump(), 200
-
-
 @api.BLUEPRINT.route("/keys/get/<fingerprint>")
 @quart_schema.validate_response(models.api.KeysGetResults, 200)
 async def keys_get(fingerprint: str) -> DictResponse:
@@ -569,68 +520,44 @@ async def keys_user(asf_uid: str) -> DictResponse:
     ).model_dump(), 200
 
 
-# TODO: Call this release/paths
[email protected]("/list/<project>/<version>")
[email protected]("/list/<project>/<version>/<revision>")
-@quart_schema.validate_response(models.api.ListResults, 200)
-async def list_endpoint(project: str, version: str, revision: str | None = 
None) -> DictResponse:
-    _simple_check(project, version, revision)
[email protected]("/projects/get/<name>")
+@quart_schema.validate_response(models.api.ProjectsGetResults, 200)
+async def projects_get(name: str) -> DictResponse:
+    _simple_check(name)
     async with db.session() as data:
-        release_name = sql.release_name(project, version)
-        release = await 
data.release(name=release_name).demand(exceptions.NotFound())
-        if revision is None:
-            dir_path = util.release_directory(release)
-        else:
-            await data.revision(release_name=release_name, 
number=revision).demand(exceptions.NotFound())
-            dir_path = util.release_directory_version(release) / revision
-    if not (await aiofiles.os.path.isdir(dir_path)):
-        raise exceptions.NotFound("Files not found")
-    files: list[str] = [str(path) for path in [p async for p in 
util.paths_recursive(dir_path)]]
-    files.sort()
-    return models.api.ListResults(
-        endpoint="/list",
-        rel_paths=files,
+        project = await data.project(name=name).demand(exceptions.NotFound())
+    return models.api.ProjectsGetResults(
+        endpoint="/projects/get",
+        project=project,
     ).model_dump(), 200
 
 
[email protected]("/project/<name>")
-@quart_schema.validate_response(models.api.ProjectResults, 200)
-async def project(name: str) -> DictResponse:
-    _simple_check(name)
[email protected]("/projects/list")
+@quart_schema.validate_response(models.api.ProjectsListResults, 200)
+async def projects_list() -> DictResponse:
+    """List all projects in the database."""
+    # TODO: Add pagination?
     async with db.session() as data:
-        project = await data.project(name=name).demand(exceptions.NotFound())
-    return models.api.ProjectResults(
-        endpoint="/project",
-        project=project,
+        projects = await data.project().all()
+    return models.api.ProjectsListResults(
+        endpoint="/projects/list",
+        projects=projects,
     ).model_dump(), 200
 
 
[email protected]("/project/releases/<name>")
-@quart_schema.validate_response(models.api.ProjectReleasesResults, 200)
-async def project_releases(name: str) -> DictResponse:
[email protected]("/projects/releases/<name>")
+@quart_schema.validate_response(models.api.ProjectsReleasesResults, 200)
+async def projects_releases(name: str) -> DictResponse:
     """List all releases for a specific project."""
     _simple_check(name)
     async with db.session() as data:
         releases = await data.release(project_name=name).all()
-    return models.api.ProjectReleasesResults(
-        endpoint="/project/releases",
+    return models.api.ProjectsReleasesResults(
+        endpoint="/projects/releases",
         releases=releases,
     ).model_dump(), 200
 
 
[email protected]("/projects")
-@quart_schema.validate_response(models.api.ProjectsResults, 200)
-async def projects() -> DictResponse:
-    """List all projects in the database."""
-    # TODO: Add pagination?
-    async with db.session() as data:
-        projects = await data.project().all()
-    return models.api.ProjectsResults(
-        endpoint="/projects",
-        projects=projects,
-    ).model_dump(), 200
-
-
 @api.BLUEPRINT.route("/releases")
 @quart_schema.validate_querystring(models.api.ReleasesQuery)
 @quart_schema.validate_response(models.api.ReleasesResults, 200)
@@ -714,6 +641,29 @@ async def releases_delete(data: 
models.api.ReleasesDeleteArgs) -> DictResponse:
     ).model_dump(), 200
 
 
[email protected]("/releases/paths/<project>/<version>")
[email protected]("/releases/paths/<project>/<version>/<revision>")
+@quart_schema.validate_response(models.api.ReleasesPathsResults, 200)
+async def release_paths(project: str, version: str, revision: str | None = 
None) -> DictResponse:
+    _simple_check(project, version, revision)
+    async with db.session() as data:
+        release_name = sql.release_name(project, version)
+        release = await 
data.release(name=release_name).demand(exceptions.NotFound())
+        if revision is None:
+            dir_path = util.release_directory(release)
+        else:
+            await data.revision(release_name=release_name, 
number=revision).demand(exceptions.NotFound())
+            dir_path = util.release_directory_version(release) / revision
+    if not (await aiofiles.os.path.isdir(dir_path)):
+        raise exceptions.NotFound("Files not found")
+    files: list[str] = [str(path) for path in [p async for p in 
util.paths_recursive(dir_path)]]
+    files.sort()
+    return models.api.ReleasesPathsResults(
+        endpoint="/releases/paths",
+        rel_paths=files,
+    ).model_dump(), 200
+
+
 @api.BLUEPRINT.route("/releases/project/<project>")
 @quart_schema.validate_querystring(models.api.ReleasesProjectQuery)
 async def releases_project(project: str, query_args: 
models.api.ReleasesProjectQuery) -> DictResponse:
diff --git a/atr/models/api.py b/atr/models/api.py
index 2abeb5f..61c82cc 100644
--- a/atr/models/api.py
+++ b/atr/models/api.py
@@ -99,11 +99,6 @@ class DraftDeleteResults(schema.Strict):
     success: str = schema.Field(..., **example("Draft 'example-0.0.1' 
deleted"))
 
 
-class ListResults(schema.Strict):
-    endpoint: Literal["/list"] = schema.Field(alias="endpoint")
-    rel_paths: Sequence[str]
-
-
 class JwtCreateArgs(schema.Strict):
     asfuid: str = schema.Field(..., **example("user"))
     pat: str = schema.Field(..., 
**example("8M5t4GCU63EdOy4NNXgXn7o-bc-muK8TRg5W-DeBaWY"))
@@ -115,18 +110,6 @@ class JwtCreateResults(schema.Strict):
     jwt: str = schema.Field(..., 
**example("eyJhbGciOiJIUzI1[...]mMjLiuyu5CSpyHI="))
 
 
[email protected]
-class KeysQuery:
-    offset: int = 0
-    limit: int = 20
-
-
-class KeysResults(schema.Strict):
-    endpoint: Literal["/keys"] = schema.Field(alias="endpoint")
-    data: Sequence[sql.PublicSigningKey]
-    count: int = schema.Field(..., **example(10))
-
-
 class KeysAddArgs(schema.Strict):
     asfuid: str = schema.Field(..., **example("user"))
     key: str = schema.Field(
@@ -141,11 +124,6 @@ class KeysAddResults(schema.Strict):
     fingerprint: str = schema.Field(..., 
**example("0123456789abcdef0123456789abcdef01234567"))
 
 
-# class KeysCommitteeResults(schema.Strict):
-#     endpoint: Literal["/keys/committee"] = schema.Field(alias="endpoint")
-#     keys: Sequence[sql.PublicSigningKey]
-
-
 class KeysDeleteArgs(schema.Strict):
     fingerprint: str = schema.Field(..., 
**example("0123456789abcdef0123456789abcdef01234567"))
 
@@ -207,19 +185,19 @@ class KeysUserResults(schema.Strict):
     keys: Sequence[sql.PublicSigningKey]
 
 
-class ProjectResults(schema.Strict):
-    endpoint: Literal["/project"] = schema.Field(alias="endpoint")
+class ProjectsGetResults(schema.Strict):
+    endpoint: Literal["/projects/get"] = schema.Field(alias="endpoint")
     project: sql.Project
 
 
-class ProjectReleasesResults(schema.Strict):
-    endpoint: Literal["/project/releases"] = schema.Field(alias="endpoint")
-    releases: Sequence[sql.Release]
+class ProjectsListResults(schema.Strict):
+    endpoint: Literal["/projects/list"] = schema.Field(alias="endpoint")
+    projects: Sequence[sql.Project]
 
 
-class ProjectsResults(schema.Strict):
-    endpoint: Literal["/projects"] = schema.Field(alias="endpoint")
-    projects: Sequence[sql.Project]
+class ProjectsReleasesResults(schema.Strict):
+    endpoint: Literal["/projects/releases"] = schema.Field(alias="endpoint")
+    releases: Sequence[sql.Release]
 
 
 @dataclasses.dataclass
@@ -255,6 +233,11 @@ class ReleasesDeleteResults(schema.Strict):
     deleted: str
 
 
+class ReleasesPathsResults(schema.Strict):
+    endpoint: Literal["/releases/paths"] = schema.Field(alias="endpoint")
+    rel_paths: Sequence[str]
+
+
 @dataclasses.dataclass
 class ReleasesProjectQuery:
     limit: int = 20
@@ -426,20 +409,18 @@ Results = Annotated[
     | CommitteesProjectsResults
     | DraftDeleteResults
     | JwtCreateResults
-    | KeysResults
     | KeysAddResults
     | KeysDeleteResults
     | KeysGetResults
-    # | KeysCommitteeResults
     | KeysUploadResults
     | KeysUserResults
-    | ListResults
-    | ProjectResults
-    | ProjectReleasesResults
-    | ProjectsResults
+    | ProjectsGetResults
+    | ProjectsListResults
+    | ProjectsReleasesResults
     | ReleasesResults
     | ReleasesCreateResults
     | ReleasesDeleteResults
+    | ReleasesPathsResults
     | ReleasesProjectResults
     | ReleasesVersionResults
     | ReleasesRevisionsResults
@@ -479,20 +460,18 @@ validate_committees_list = 
validator(CommitteesListResults)
 validate_committees_projects = validator(CommitteesProjectsResults)
 validate_draft_delete = validator(DraftDeleteResults)
 validate_jwt_create = validator(JwtCreateResults)
-validate_keys = validator(KeysResults)
 validate_keys_add = validator(KeysAddResults)
-# validate_keys_committee = validator(KeysCommitteeResults)
 validate_keys_delete = validator(KeysDeleteResults)
 validate_keys_get = validator(KeysGetResults)
 validate_keys_upload = validator(KeysUploadResults)
 validate_keys_user = validator(KeysUserResults)
-validate_list = validator(ListResults)
-validate_project = validator(ProjectResults)
-validate_project_releases = validator(ProjectReleasesResults)
-validate_projects = validator(ProjectsResults)
+validate_projects_get = validator(ProjectsGetResults)
+validate_projects_list = validator(ProjectsListResults)
+validate_projects_releases = validator(ProjectsReleasesResults)
 validate_releases = validator(ReleasesResults)
 validate_releases_create = validator(ReleasesCreateResults)
 validate_releases_delete = validator(ReleasesDeleteResults)
+validate_releases_paths = validator(ReleasesPathsResults)
 validate_releases_project = validator(ReleasesProjectResults)
 validate_releases_version = validator(ReleasesVersionResults)
 validate_releases_revisions = validator(ReleasesRevisionsResults)


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

Reply via email to