This is an automated email from the ASF dual-hosted git repository.
arm pushed a commit to branch arm
in repository https://gitbox.apache.org/repos/asf/tooling-trusted-releases.git
The following commit(s) were added to refs/heads/arm by this push:
new 16386f54 #765: usafe safe values for distribution params
16386f54 is described below
commit 16386f545c5821fcca5f896b3ad73fa7ac8d11df
Author: Alastair McFarlane <[email protected]>
AuthorDate: Thu Mar 12 09:58:53 2026 +0000
#765: usafe safe values for distribution params
---
atr/models/api.py | 18 +++++++--------
atr/models/distribution.py | 8 +++----
atr/models/sql.py | 12 +++++++++-
atr/shared/distribution.py | 43 ++++++++++++++++++++----------------
atr/storage/writers/distributions.py | 33 +++++++++++++--------------
atr/tasks/distribution.py | 9 +-------
6 files changed, 66 insertions(+), 57 deletions(-)
diff --git a/atr/models/api.py b/atr/models/api.py
index 342773b2..514a7f6d 100644
--- a/atr/models/api.py
+++ b/atr/models/api.py
@@ -103,9 +103,9 @@ class DistributionRecordArgs(schema.Strict):
project: safe.ProjectName = schema.example("example")
version: safe.VersionName = schema.example("0.0.1")
platform: sql.DistributionPlatform =
schema.example(sql.DistributionPlatform.ARTIFACT_HUB)
- distribution_owner_namespace: str | None = schema.default_example(None,
"example")
- distribution_package: str = schema.example("example")
- distribution_version: str = schema.example("0.0.1")
+ distribution_owner_namespace: safe.Alphanumeric | None =
schema.default_example(None, "example")
+ distribution_package: safe.Alphanumeric = schema.example("example")
+ distribution_version: safe.VersionName = schema.example("0.0.1")
staging: bool = schema.example(False)
details: bool = schema.example(False)
@@ -131,9 +131,9 @@ class DistributionRecordFromWorkflowArgs(schema.Strict):
project: safe.ProjectName = schema.example("example")
version: safe.VersionName = schema.example("0.0.1")
platform: sql.DistributionPlatform =
schema.example(sql.DistributionPlatform.ARTIFACT_HUB)
- distribution_owner_namespace: str | None = schema.default_example(None,
"example")
- distribution_package: str = schema.example("example")
- distribution_version: str = schema.example("0.0.1")
+ distribution_owner_namespace: safe.Alphanumeric | None =
schema.default_example(None, "example")
+ distribution_package: safe.Alphanumeric = schema.example("example")
+ distribution_version: safe.VersionName = schema.example("0.0.1")
phase: str = schema.Field(strict=False, default="compose",
json_schema_extra={"examples": ["compose", "finish"]})
staging: bool = schema.example(False)
details: bool = schema.example(False)
@@ -327,9 +327,9 @@ class PublisherDistributionRecordArgs(schema.Strict):
jwt: str = schema.example("eyJhbGciOiJIUzI1[...]mMjLiuyu5CSpyHI=")
version: safe.VersionName = schema.example("0.0.1")
platform: sql.DistributionPlatform =
schema.example(sql.DistributionPlatform.ARTIFACT_HUB)
- distribution_owner_namespace: str | None = schema.default_example(None,
"example")
- distribution_package: str = schema.example("example")
- distribution_version: str = schema.example("0.0.1")
+ distribution_owner_namespace: safe.Alphanumeric | None =
schema.default_example(None, "example")
+ distribution_package: safe.Alphanumeric = schema.example("example")
+ distribution_version: safe.VersionName = schema.example("0.0.1")
staging: bool = schema.example(False)
details: bool = schema.example(False)
diff --git a/atr/models/distribution.py b/atr/models/distribution.py
index 3dfae1b3..7e5f3149 100644
--- a/atr/models/distribution.py
+++ b/atr/models/distribution.py
@@ -19,7 +19,7 @@ import datetime
import pydantic
-from . import basic, schema, sql
+from . import basic, safe, schema, sql
class ArtifactHubAvailableVersion(schema.Subset):
@@ -93,9 +93,9 @@ class PyPIResponse(schema.Subset):
# Including all of the enum properties
class Data(schema.Subset):
platform: sql.DistributionPlatform
- owner_namespace: str | None = None
- package: str
- version: str
+ owner_namespace: safe.Alphanumeric | None = None
+ package: safe.Alphanumeric
+ version: safe.VersionName
details: bool
@pydantic.field_validator("owner_namespace", mode="before")
diff --git a/atr/models/sql.py b/atr/models/sql.py
index ac70f282..78c47f26 100644
--- a/atr/models/sql.py
+++ b/atr/models/sql.py
@@ -34,7 +34,7 @@ import sqlalchemy.orm as orm
import sqlalchemy.sql.expression as expression
import sqlmodel
-from . import results, safe, schema
+from . import distribution, results, safe, schema
T = TypeVar("T")
@@ -1066,6 +1066,16 @@ class Distribution(sqlmodel.SQLModel, table=True):
# So we do not store it in the database
# api_response: Any =
sqlmodel.Field(sa_column=sqlalchemy.Column(sqlalchemy.JSON))
+ def distribution_data(self, details: bool = False) -> distribution.Data:
+ """Get a distribution data object"""
+ return distribution.Data(
+ platform=self.platform,
+ owner_namespace=safe.Alphanumeric(self.owner_namespace),
+ package=safe.Alphanumeric(self.package),
+ version=safe.VersionName(self.version),
+ details=details,
+ )
+
@property
def identifier(self) -> str:
def normal(text: str) -> str:
diff --git a/atr/shared/distribution.py b/atr/shared/distribution.py
index b565f6ba..922e02db 100644
--- a/atr/shared/distribution.py
+++ b/atr/shared/distribution.py
@@ -126,13 +126,13 @@ class DistributionAutomateForm(form.Form):
platform: form.Enum[DistributionPlatform] = form.label(
"Platform", widget=form.Widget.SELECT,
enum_filter_include=[DistributionPlatform.MAVEN.value]
)
- owner_namespace: str = form.label(
+ owner_namespace: safe.Alphanumeric = form.label(
"Owner or Namespace",
"Who owns or names the package (Maven groupId, npm @scope, Docker
namespace, "
"GitHub owner, ArtifactHub repo). Leave blank if not used.",
)
- package: str = form.label("Package")
- version: str = form.label("Version")
+ package: safe.Alphanumeric = form.label("Package")
+ version: safe.VersionName = form.label("Version")
details: form.Bool = form.label(
"Include details",
"Include the details of the distribution in the response",
@@ -159,13 +159,13 @@ class DistributionAutomateForm(form.Form):
class DistributionRecordForm(form.Form):
platform: form.Enum[DistributionPlatform] = form.label("Platform",
widget=form.Widget.SELECT)
- owner_namespace: str = form.label(
+ owner_namespace: safe.Alphanumeric = form.label(
"Owner or Namespace",
"Who owns or names the package (Maven groupId, npm @scope, Docker
namespace, "
"GitHub owner, ArtifactHub repo). Leave blank if not used.",
)
- package: str = form.label("Package")
- version: str = form.label("Version")
+ package: safe.Alphanumeric = form.label("Package")
+ version: safe.VersionName = form.label("Version")
details: form.Bool = form.label(
"Include details",
"Include the details of the distribution in the response",
@@ -193,8 +193,9 @@ class DistributionRecordForm(form.Form):
def distribution_upload_date( # noqa: C901
platform: sql.DistributionPlatform,
data: basic.JSON,
- version: str,
+ version_name: safe.VersionName,
) -> datetime.datetime | None:
+ version = str(version_name)
match platform:
case sql.DistributionPlatform.ARTIFACT_HUB:
if not (versions :=
distribution.ArtifactHubResponse.model_validate(data).available_versions):
@@ -236,7 +237,7 @@ def distribution_upload_date( # noqa: C901
def distribution_web_url( # noqa: C901
platform: sql.DistributionPlatform,
data: basic.JSON,
- version: str,
+ version: safe.VersionName,
) -> str | None:
match platform:
case sql.DistributionPlatform.ARTIFACT_HUB:
@@ -247,7 +248,7 @@ def distribution_web_url( # noqa: C901
if repo_name and pkg_name:
if ver:
return
f"https://artifacthub.io/packages/helm/{repo_name}/{pkg_name}/{ver}"
- return
f"https://artifacthub.io/packages/helm/{repo_name}/{pkg_name}/{version}"
+ return
f"https://artifacthub.io/packages/helm/{repo_name}/{pkg_name}/{version!s}"
if ah.home_url:
return ah.home_url
for link in ah.links:
@@ -266,7 +267,7 @@ def distribution_web_url( # noqa: C901
case sql.DistributionPlatform.NPM:
nr = distribution.NpmResponse.model_validate(data)
# return nr.homepage
- return f"https://www.npmjs.com/package/{nr.name}/v/{version}"
+ return f"https://www.npmjs.com/package/{nr.name}/v/{version!s}"
case sql.DistributionPlatform.NPM_SCOPED:
nr = distribution.NpmResponse.model_validate(data)
# TODO: This is not correct
@@ -278,17 +279,18 @@ def distribution_web_url( # noqa: C901
def get_api_url(dd: distribution.Data, staging: bool | None = None):
+ namespace = str(dd.owner_namespace) if dd.owner_namespace else None
template_url = _template_url(dd, staging)
- package = urllib.parse.quote(dd.package)
- version = urllib.parse.quote(dd.version)
+ package = urllib.parse.quote(str(dd.package))
+ version = urllib.parse.quote(str(dd.version))
api_url = template_url.format(
- owner_namespace=dd.owner_namespace,
+ owner_namespace=namespace,
package=package,
version=version,
)
if dd.platform == sql.DistributionPlatform.MAVEN:
# We do this here because the CDNs break the namespace up into a /
delimited URL
- owner = (dd.owner_namespace or "").replace(".", "/")
+ owner = (namespace or "").replace(".", "/")
api_url = template_url.format(
owner_namespace=owner,
package=package,
@@ -298,11 +300,12 @@ def get_api_url(dd: distribution.Data, staging: bool |
None = None):
def html_submitted_values_table(block: htm.Block, dd: distribution.Data) ->
None:
+ namespace = str(dd.owner_namespace) if dd.owner_namespace else "-"
tbody = htm.tbody[
html_tr("Platform", dd.platform.name),
- html_tr("Owner or Namespace", dd.owner_namespace or "-"),
- html_tr("Package", dd.package),
- html_tr("Version", dd.version),
+ html_tr("Owner or Namespace", namespace),
+ html_tr("Package", str(dd.package)),
+ html_tr("Version", str(dd.version)),
]
block.table(".table.table-striped.table-bordered")[tbody]
@@ -316,8 +319,9 @@ def html_tr_a(label: str, value: str | None) -> htm.Element:
async def json_from_distribution_platform(
- api_url: str, platform: sql.DistributionPlatform, version: str
+ api_url: str, platform: sql.DistributionPlatform, version_name:
safe.VersionName
) -> outcome.Outcome[basic.JSON]:
+ version = str(version_name)
try:
async with util.create_secure_session() as session:
async with session.get(api_url) as response:
@@ -334,11 +338,12 @@ async def json_from_distribution_platform(
return outcome.Result(result)
-async def json_from_maven_xml(api_url: str, version: str) ->
outcome.Outcome[basic.JSON]:
+async def json_from_maven_xml(api_url: str, version_name: safe.VersionName) ->
outcome.Outcome[basic.JSON]:
import datetime
import defusedxml.ElementTree as ElementTree
+ version = str(version_name)
try:
async with util.create_secure_session() as session:
async with session.get(api_url) as response:
diff --git a/atr/storage/writers/distributions.py
b/atr/storage/writers/distributions.py
index 120241b4..f9707c83 100644
--- a/atr/storage/writers/distributions.py
+++ b/atr/storage/writers/distributions.py
@@ -97,22 +97,22 @@ class CommitteeMember(CommitteeParticipant):
release_name: models.safe.ReleaseName,
platform: models.sql.DistributionPlatform,
committee_name: str,
- owner_namespace: str | None,
+ owner_namespace: models.safe.Alphanumeric | None,
project_name: models.safe.ProjectName,
version_name: models.safe.VersionName,
phase: str,
revision_number: str | None,
- package: str,
- version: str,
+ package: models.safe.Alphanumeric,
+ version: models.safe.VersionName,
staging: bool,
) -> models.sql.Task:
dist_task = models.sql.Task(
task_type=models.sql.TaskType.DISTRIBUTION_WORKFLOW,
task_args=gha.DistributionWorkflow(
name=str(release_name),
- namespace=owner_namespace or "",
- package=package,
- version=version,
+ namespace=str(owner_namespace) if owner_namespace else "",
+ package=str(package),
+ version=str(version),
project_name=str(project_name),
version_name=str(version_name),
phase=phase,
@@ -138,24 +138,25 @@ class CommitteeMember(CommitteeParticipant):
self,
release_name: models.safe.ReleaseName,
platform: models.sql.DistributionPlatform,
- owner_namespace: str | None,
- package: str,
- version: str,
+ owner_namespace: models.safe.Alphanumeric | None,
+ package: models.safe.Alphanumeric,
+ version: models.safe.VersionName,
staging: bool,
pending: bool,
upload_date: datetime.datetime | None,
api_url: str | None = None,
web_url: str | None = None,
) -> tuple[models.sql.Distribution, bool]:
+ namespace = str(owner_namespace) if owner_namespace else ""
existing = await self.__data.distribution(
- str(release_name), platform, owner_namespace or "", package,
version
+ str(release_name), platform, namespace, str(package), str(version)
).get()
dist = models.sql.Distribution(
platform=platform,
release_name=str(release_name),
- owner_namespace=owner_namespace or "",
- package=package,
- version=version,
+ owner_namespace=namespace,
+ package=str(package),
+ version=str(version),
staging=staging,
pending=pending,
retries=0,
@@ -173,9 +174,9 @@ class CommitteeMember(CommitteeParticipant):
upgraded = await self.__upgrade_staging_to_final(
release_name,
platform,
- owner_namespace,
- package,
- version,
+ namespace,
+ str(package),
+ str(version),
pending,
upload_date,
api_url,
diff --git a/atr/tasks/distribution.py b/atr/tasks/distribution.py
index 0c962e9c..b6a0caf1 100644
--- a/atr/tasks/distribution.py
+++ b/atr/tasks/distribution.py
@@ -20,7 +20,6 @@ import pydantic
import atr.db as db
import atr.log as log
-import atr.models as models
import atr.models.results as results
import atr.models.schema as schema
import atr.shared.distribution as distribution
@@ -46,13 +45,7 @@ async def status_check(args: DistributionStatusCheckArgs, *,
task_id: int | None
dists = await data.distribution(pending=True, _with_release=True,
_with_release_project=True).all()
for dist in dists:
name = f"{dist.platform} {dist.owner_namespace} {dist.package}
{dist.version}"
- dd = models.distribution.Data(
- platform=dist.platform,
- owner_namespace=dist.owner_namespace,
- package=dist.package,
- version=dist.version,
- details=False,
- )
+ dd = dist.distribution_data()
if not dist.created_by:
log.warning(f"Distribution {name} has no creator, skipping")
continue
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]