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-releases-client.git
The following commit(s) were added to refs/heads/main by this push:
new 44da03d Use API output discriminators to automatically detect types
44da03d is described below
commit 44da03da310375284e0eb35c4af96a560f608f4c
Author: Sean B. Palmer <[email protected]>
AuthorDate: Mon Jul 14 19:37:32 2025 +0100
Use API output discriminators to automatically detect types
---
pyproject.toml | 4 ++--
src/atrclient/client.py | 4 ++--
src/atrclient/models/api.py | 31 +++++++++++++++++++++++++++----
src/atrclient/models/results.py | 4 ++--
uv.lock | 4 ++--
5 files changed, 35 insertions(+), 12 deletions(-)
diff --git a/pyproject.toml b/pyproject.toml
index 92faecd..d4e267b 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -11,7 +11,7 @@ build-backend = "hatchling.build"
[project]
name = "apache-trusted-releases"
-version = "0.20250714.1815"
+version = "0.20250714.1835"
description = "ATR CLI and Python API"
readme = "README.md"
requires-python = ">=3.13"
@@ -72,4 +72,4 @@ select = [
]
[tool.uv]
-exclude-newer = "2025-07-14T18:15:00Z"
+exclude-newer = "2025-07-14T18:35:00Z"
diff --git a/src/atrclient/client.py b/src/atrclient/client.py
index d849695..4a2019f 100755
--- a/src/atrclient/client.py
+++ b/src/atrclient/client.py
@@ -170,8 +170,8 @@ def app_checks_wait(
url += f"/{revision}"
result = asyncio.run(web_get(url, jwt_value, verify_ssl))
try:
- result_count = models.api.ResultCount.model_validate(result)
- except pydantic.ValidationError as e:
+ result_count = models.api.validate_count(result)
+ except (pydantic.ValidationError, models.api.ResultsTypeError) as e:
show_error_and_exit(f"Unexpected API response: {result}\n{e}")
if result_count.count == 0:
break
diff --git a/src/atrclient/models/api.py b/src/atrclient/models/api.py
index bb668ac..1662806 100644
--- a/src/atrclient/models/api.py
+++ b/src/atrclient/models/api.py
@@ -16,10 +16,17 @@
# under the License.
import dataclasses
+from typing import Annotated, Any, Literal
+
+import pydantic
from . import schema
+class ResultsTypeError(TypeError):
+ pass
+
+
@dataclasses.dataclass
class Pagination:
offset: int = 0
@@ -43,6 +50,11 @@ class AsfuidPat(schema.Strict):
pat: str
+class Count(schema.Strict):
+ kind: Literal["count"] = schema.Field(alias="kind")
+ count: int
+
+
class ProjectVersion(schema.Strict):
project: str
version: str
@@ -55,10 +67,6 @@ class ProjectVersionRelpathContent(schema.Strict):
content: str
-class ResultCount(schema.Strict):
- count: int
-
-
class VoteStart(schema.Strict):
project: str
version: str
@@ -67,3 +75,18 @@ class VoteStart(schema.Strict):
vote_duration: int
subject: str
body: str
+
+
+Results = Annotated[
+ Count,
+ schema.Field(discriminator="kind"),
+]
+
+ResultsAdapter = pydantic.TypeAdapter(Results)
+
+
+def validate_count(value: Any) -> Count:
+ count = ResultsAdapter.validate_python(value)
+ if not isinstance(count, Count):
+ raise ResultsTypeError(f"Invalid API response: {value}")
+ return count
diff --git a/src/atrclient/models/results.py b/src/atrclient/models/results.py
index 5f6c6f6..0f9bee0 100644
--- a/src/atrclient/models/results.py
+++ b/src/atrclient/models/results.py
@@ -17,7 +17,7 @@
from typing import Annotated, Literal
-from pydantic import TypeAdapter
+import pydantic
from . import schema
@@ -70,4 +70,4 @@ Results = Annotated[
schema.Field(discriminator="kind"),
]
-ResultsAdapter = TypeAdapter(Results)
+ResultsAdapter = pydantic.TypeAdapter(Results)
diff --git a/uv.lock b/uv.lock
index 30c2a88..cd4650c 100644
--- a/uv.lock
+++ b/uv.lock
@@ -2,7 +2,7 @@ version = 1
requires-python = ">=3.13"
[options]
-exclude-newer = "2025-07-14T18:15:00Z"
+exclude-newer = "2025-07-14T18:35:00Z"
[[package]]
name = "aiohappyeyeballs"
@@ -83,7 +83,7 @@ wheels = [
[[package]]
name = "apache-trusted-releases"
-version = "0.20250714.1815"
+version = "0.20250714.1835"
source = { editable = "." }
dependencies = [
{ name = "aiohttp" },
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]