Skip to content

Commit 453cdc8

Browse files
authored
Move signing to optional module. (#225)
* Temp fixed uv issue for hatch test by adding direct dependencies * Users will be notified to install optional dependencies when using `sign=True` See b/395859806 and #224
1 parent a4dc3dd commit 453cdc8

File tree

4 files changed

+52
-26
lines changed

4 files changed

+52
-26
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## Next Release
44

5-
*
5+
* Moved signing as optional feature due to dependency issue.
66

77
## v0.3.7 (January 31, 2025)
88

pyproject.toml

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ dependencies = [
2424
"requests",
2525
"tqdm",
2626
"packaging",
27-
"model_signing",
2827
]
2928

3029
[project.urls]
@@ -34,7 +33,7 @@ dependencies = [
3433
[project.optional-dependencies]
3534
hf-datasets = ["datasets", "kagglehub[pandas-datasets]"]
3635
pandas-datasets = ["pandas"]
37-
36+
signing = [ "model_signing", "sigstore>=3.6.1", "betterproto>=2.0.0b6"]
3837

3938
# twine 6.0.1 doesn't support metadata-version 2.4.
4039
# remove `core-metadata-version` pin once twine release a new version with: https://github.com/pypa/twine/pull/1180
@@ -57,8 +56,7 @@ dependencies = [
5756
"openpyxl",
5857
"pyjwt[crypto]",
5958
]
60-
features = ["hf-datasets"]
61-
installer = "pip"
59+
features = ["hf-datasets", "signing"]
6260

6361
[[tool.hatch.envs.hatch-test.matrix]]
6462
python = ["3.9", "3.10", "3.11", "3.12"]
@@ -118,6 +116,14 @@ features = [
118116
"pandas-datasets",
119117
]
120118

119+
# Signing is unable to be installed via uv without a prerelease library: b/395859806
120+
[tool.hatch.envs.signing]
121+
dependencies = [
122+
]
123+
features = [
124+
"signing",
125+
]
126+
121127
[tool.black]
122128
target-version = ["py39"]
123129
line-length = 120

src/kagglehub/models.py

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
import logging
2-
from pathlib import Path
32
from typing import Optional, Union
43

5-
from model_signing.api import SigningConfig
6-
74
from kagglehub import registry
85
from kagglehub.gcs_upload import normalize_patterns, upload_files_and_directories
96
from kagglehub.handle import parse_model_handle
107
from kagglehub.logger import EXTRA_CONSOLE_BLOCK
11-
from kagglehub.models_helpers import create_model_if_missing, create_model_instance_or_version, signing_token
8+
from kagglehub.models_helpers import create_model_if_missing, create_model_instance_or_version
9+
from kagglehub.signing import sign_with_sigstore
1210

1311
logger = logging.getLogger(__name__)
1412

@@ -76,23 +74,14 @@ def model_upload(
7674
# Model can be non-existent. Get token after model creation so signing token can be authorized.
7775
try:
7876
if sigstore:
79-
token = signing_token(h.owner, h.model)
80-
if token:
81-
signing_file = Path(local_model_dir) / ".kaggle" / "signing.json"
82-
signing_file.parent.mkdir(exist_ok=True, parents=True)
83-
signing_file.unlink(missing_ok=True)
84-
# The below will throw an exception if the token can't be verified (Needs to be a production token)
85-
# Setting KAGGLE_API_ENDPOINT to localhost will throw the exception as stated above.
86-
SigningConfig().set_sigstore_signer(identity_token=token, use_staging=False).sign(
87-
Path(local_model_dir), signing_file
88-
)
89-
else:
90-
# skips transparency log publishing as we are unable to get a token
91-
sigstore = False
92-
logger.warning("Unable to retrieve identity token. Skipping signing...")
93-
except Exception:
94-
logger.exception("Signing failed. Skipping signing...")
95-
sigstore = False
77+
sigstore = sign_with_sigstore(local_model_dir, h)
78+
except ImportError:
79+
import_warning_message = (
80+
"The 'model_upload(...sign=True)' function requires the 'kagglehub[signing]' extras. "
81+
"Install them with 'pip install kagglehub[signing]'"
82+
)
83+
# Inform the user if we detect that they didn't install everything
84+
raise ImportError(import_warning_message) from None
9685

9786
# Upload the model files to GCS
9887
tokens = upload_files_and_directories(

src/kagglehub/signing.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import logging
2+
from pathlib import Path
3+
4+
from kagglehub.handle import ModelHandle
5+
from kagglehub.models_helpers import signing_token
6+
7+
logger = logging.getLogger(__name__)
8+
9+
10+
def sign_with_sigstore(local_model_dir: str, handle: ModelHandle) -> bool:
11+
from model_signing.api import SigningConfig
12+
13+
try:
14+
token = signing_token(handle.owner, handle.model)
15+
if token:
16+
signing_file = Path(local_model_dir) / ".kaggle" / "signing.json"
17+
signing_file.parent.mkdir(exist_ok=True, parents=True)
18+
signing_file.unlink(missing_ok=True)
19+
# The below will throw an exception if the token can't be verified (Needs to be a production token)
20+
# Setting KAGGLE_API_ENDPOINT to localhost will throw the exception as stated above.
21+
SigningConfig().set_sigstore_signer(identity_token=token, use_staging=False).sign(
22+
Path(local_model_dir), signing_file
23+
)
24+
return True
25+
else:
26+
# skips transparency log publishing as we are unable to get a token
27+
logger.warning("Unable to retrieve identity token. Skipping signing...")
28+
return False
29+
except Exception:
30+
logger.exception("Signing failed. Skipping signing...")
31+
return False

0 commit comments

Comments
 (0)