From 45fc60095ab58929d186bcd4775013204526b25e Mon Sep 17 00:00:00 2001 From: Matteo Fari Date: Fri, 23 Jan 2026 11:28:23 +0100 Subject: [PATCH] fix(models): break circular import with Rekor clients Signed-off-by: Matteo Fari --- sigstore/_internal/rekor/client.py | 12 ++++++++++-- sigstore/_internal/rekor/client_v2.py | 7 ++++++- sigstore/models.py | 6 ++---- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/sigstore/_internal/rekor/client.py b/sigstore/_internal/rekor/client.py index 57a321885..bf4f69d70 100644 --- a/sigstore/_internal/rekor/client.py +++ b/sigstore/_internal/rekor/client.py @@ -23,7 +23,7 @@ import logging from abc import ABC from dataclasses import dataclass -from typing import Any +from typing import TYPE_CHECKING, Any import rekor_types import requests @@ -38,7 +38,9 @@ ) from sigstore.dsse import Envelope from sigstore.hashes import Hashed -from sigstore.models import TransparencyLogEntry + +if TYPE_CHECKING: + from sigstore.models import TransparencyLogEntry _logger = logging.getLogger(__name__) @@ -142,6 +144,8 @@ def get( resp.raise_for_status() except requests.HTTPError as http_error: raise RekorClientError(http_error) + from sigstore.models import TransparencyLogEntry + return TransparencyLogEntry._from_v1_response(resp.json()) def post( @@ -162,6 +166,8 @@ def post( integrated_entry = resp.json() _logger.debug(f"integrated: {integrated_entry}") + from sigstore.models import TransparencyLogEntry + return TransparencyLogEntry._from_v1_response(integrated_entry) @property @@ -204,6 +210,8 @@ def post( # We select the oldest entry for our actual return value, # since a malicious actor could conceivably spam the log with # newer duplicate entries. + from sigstore.models import TransparencyLogEntry + oldest_entry: TransparencyLogEntry | None = None for result in results: entry = TransparencyLogEntry._from_v1_response(result) diff --git a/sigstore/_internal/rekor/client_v2.py b/sigstore/_internal/rekor/client_v2.py index d4a4d0e10..74360282b 100644 --- a/sigstore/_internal/rekor/client_v2.py +++ b/sigstore/_internal/rekor/client_v2.py @@ -21,6 +21,7 @@ import base64 import json import logging +from typing import TYPE_CHECKING import requests from cryptography.hazmat.primitives import serialization @@ -38,7 +39,9 @@ ) from sigstore.dsse import Envelope from sigstore.hashes import Hashed -from sigstore.models import TransparencyLogEntry + +if TYPE_CHECKING: + from sigstore.models import TransparencyLogEntry _logger = logging.getLogger(__name__) @@ -89,6 +92,8 @@ def create_entry(self, payload: EntryRequestBody) -> TransparencyLogEntry: integrated_entry = resp.json() _logger.debug(f"integrated: {integrated_entry}") + from sigstore.models import TransparencyLogEntry + inner = _TransparencyLogEntry.from_dict(integrated_entry) return TransparencyLogEntry(inner) diff --git a/sigstore/models.py b/sigstore/models.py index 2237b772e..3c26800a2 100644 --- a/sigstore/models.py +++ b/sigstore/models.py @@ -53,6 +53,8 @@ from sigstore._internal.merkle import verify_merkle_inclusion from sigstore._internal.rekor import RekorLogSubmitter from sigstore._internal.rekor.checkpoint import verify_checkpoint +from sigstore._internal.rekor.client import RekorClient +from sigstore._internal.rekor.client_v2 import RekorV2Client from sigstore._internal.timestamp import TimestampAuthorityClient from sigstore._internal.trust import ( CertificateAuthority, @@ -757,12 +759,8 @@ def get_tlogs(self) -> list[RekorLogSubmitter]: result: list[RekorLogSubmitter] = [] for tlog in self._tlogs: if tlog.major_api_version == 1: - from sigstore._internal.rekor.client import RekorClient - result.append(RekorClient(tlog.url)) elif tlog.major_api_version == 2: - from sigstore._internal.rekor.client_v2 import RekorV2Client - result.append(RekorV2Client(tlog.url)) else: raise AssertionError(f"Unexpected Rekor v{tlog.major_api_version}")