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 5b80264  Add some API endpoints for release data
5b80264 is described below

commit 5b80264715cd6684afe2371811370efb57d2e732
Author: Sean B. Palmer <[email protected]>
AuthorDate: Wed Jul 2 19:34:38 2025 +0100

    Add some API endpoints for release data
---
 atr/blueprints/api/api.py | 69 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 69 insertions(+)

diff --git a/atr/blueprints/api/api.py b/atr/blueprints/api/api.py
index ca2bf58..6a337d4 100644
--- a/atr/blueprints/api/api.py
+++ b/atr/blueprints/api/api.py
@@ -41,6 +41,11 @@ class Pagination:
     limit: int = 20
 
 
[email protected]
+class Releases(Pagination):
+    phase: str | None = None
+
+
 @dataclasses.dataclass
 class Task(Pagination):
     status: str | None = None
@@ -140,6 +145,70 @@ async def projects_name_releases(name: str) -> 
tuple[list[Mapping], int]:
         return [release.model_dump() for release in releases], 200
 
 
[email protected]("/releases")
+@quart_schema.validate_querystring(Releases)
+async def releases(query_args: Releases) -> quart.Response:
+    """Paged list of releases with optional filtering by phase."""
+    _pagination_args_validate(query_args)
+    via = models.validate_instrumented_attribute
+    async with db.session() as data:
+        statement = sqlmodel.select(models.Release)
+
+        if query_args.phase:
+            try:
+                phase_value = models.ReleasePhase(query_args.phase)
+            except ValueError:
+                raise exceptions.BadRequest(f"Invalid phase: 
{query_args.phase}")
+            statement = statement.where(models.Release.phase == phase_value)
+
+        statement = (
+            
statement.order_by(via(models.Release.created).desc()).limit(query_args.limit).offset(query_args.offset)
+        )
+
+        paged_releases = (await data.execute(statement)).scalars().all()
+
+        count_stmt = 
sqlalchemy.select(sqlalchemy.func.count(via(models.Release.name)))
+        if query_args.phase:
+            phase_value = models.ReleasePhase(query_args.phase) if 
query_args.phase else None
+            if phase_value is not None:
+                count_stmt = count_stmt.where(via(models.Release.phase) == 
phase_value)
+
+        count = (await data.execute(count_stmt)).scalar_one()
+
+        result = {"data": [release.model_dump() for release in 
paged_releases], "count": count}
+        return quart.jsonify(result)
+
+
[email protected]("/releases/<project>/<version>")
+@quart_schema.validate_response(models.Release, 200)
+async def releases_project_version(project: str, version: str) -> 
tuple[Mapping, int]:
+    """Return a single release by project and version."""
+    async with db.session() as data:
+        release_name = models.release_name(project, version)
+        release = await 
data.release(name=release_name).demand(exceptions.NotFound())
+        return release.model_dump(), 200
+
+
[email protected]("/releases/<project>/<version>/check-results")
+@quart_schema.validate_response(list[models.CheckResult], 200)
+async def releases_project_version_check_results(project: str, version: str) 
-> tuple[list[Mapping], int]:
+    """List all check results for a given release."""
+    async with db.session() as data:
+        release_name = models.release_name(project, version)
+        check_results = await 
data.check_result(release_name=release_name).all()
+        return [cr.model_dump() for cr in check_results], 200
+
+
[email protected]("/releases/<project>/<version>/revisions")
+@quart_schema.validate_response(list[models.Revision], 200)
+async def releases_project_version_revisions(project: str, version: str) -> 
tuple[list[Mapping], int]:
+    """List all revisions for a given release."""
+    async with db.session() as data:
+        release_name = models.release_name(project, version)
+        revisions = await data.revision(release_name=release_name).all()
+        return [rev.model_dump() for rev in revisions], 200
+
+
 @api.BLUEPRINT.route("/tasks")
 @quart_schema.validate_querystring(Task)
 async def tasks(query_args: Task) -> quart.Response:


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

Reply via email to