@@ -400,7 +400,7 @@ def repo_type_and_id_from_hf_id(hf_id: str, hub_url: str | None = None) -> tuple
400400 repo_type = constants.REPO_TYPES_MAPPING[repo_type]
401401 if repo_type == "":
402402 repo_type = None
403- if repo_type not in constants.REPO_TYPES and repo_type != "bucket":
403+ if repo_type not in constants.REPO_TYPES_WITH_KERNEL and repo_type != "bucket":
404404 raise ValueError(f"Unknown `repo_type`: '{repo_type}' ('{input_hf_id}')")
405405
406406 return repo_type, namespace, repo_id
@@ -1368,6 +1368,54 @@ def __init__(self, **kwargs):
13681368 self.__dict__.update(**kwargs)
13691369
13701370
1371+ @dataclass
1372+ class KernelInfo:
1373+ """
1374+ Contains information about a kernel repo on the Hub. This object is returned by [`kernel_info`].
1375+
1376+ Attributes:
1377+ id (`str`):
1378+ ID of the kernel repo.
1379+ author (`str`, *optional*):
1380+ Author of the kernel repo.
1381+ downloads (`int`, *optional*):
1382+ Number of downloads of the kernel repo over the last 30 days.
1383+ gated (`Literal["auto", "manual", False]`, *optional*):
1384+ Is the repo gated. If so, whether there is manual or automatic approval.
1385+ last_modified (`datetime`, *optional*):
1386+ Date of last commit to the repo.
1387+ likes (`int`, *optional*):
1388+ Number of likes of the kernel repo.
1389+ private (`bool`, *optional*):
1390+ Is the repo private.
1391+ sha (`str`, *optional*):
1392+ Repo SHA at this particular revision.
1393+ """
1394+
1395+ id: str
1396+ author: str | None
1397+ downloads: int | None
1398+ gated: Literal["auto", "manual", False] | None
1399+ last_modified: datetime | None
1400+ likes: int | None
1401+ private: bool | None
1402+ sha: str | None
1403+
1404+ def __init__(self, **kwargs):
1405+ self.id = kwargs.pop("id")
1406+ self.author = kwargs.pop("author", None)
1407+ self.downloads = kwargs.pop("downloads", None)
1408+ self.gated = kwargs.pop("gated", None)
1409+ last_modified = kwargs.pop("lastModified", None) or kwargs.pop("last_modified", None)
1410+ self.last_modified = parse_datetime(last_modified) if last_modified else None
1411+ self.likes = kwargs.pop("likes", None)
1412+ self.private = kwargs.pop("private", None)
1413+ self.sha = kwargs.pop("sha", None)
1414+
1415+ # future compatibility
1416+ self.__dict__.update(**kwargs)
1417+
1418+
13711419@dataclass
13721420class CollectionItem:
13731421 """
@@ -3293,6 +3341,46 @@ def space_info(
32933341 data = r.json()
32943342 return SpaceInfo(**data)
32953343
3344+ @validate_hf_hub_args
3345+ def kernel_info(
3346+ self,
3347+ repo_id: str,
3348+ *,
3349+ revision: str | None = None,
3350+ timeout: float | None = None,
3351+ token: bool | str | None = None,
3352+ ) -> KernelInfo:
3353+ """
3354+ Get info on one specific kernel on huggingface.co.
3355+
3356+ Args:
3357+ repo_id (`str`):
3358+ A namespace (user or an organization) and a repo name separated by a `/`.
3359+ revision (`str`, *optional*):
3360+ The revision of the kernel repository from which to get the
3361+ information.
3362+ timeout (`float`, *optional*):
3363+ Whether to set a timeout for the request to the Hub.
3364+ token (`bool` or `str`, *optional*):
3365+ A valid user access token (string). Defaults to the locally saved
3366+ token, which is the recommended method for authentication (see
3367+ https://huggingface.co/docs/huggingface_hub/quick-start#authentication).
3368+ To disable authentication, pass `False`.
3369+
3370+ Returns:
3371+ [`~hf_api.ModelInfo`]: The kernel repository information.
3372+ """
3373+ headers = self._build_hf_headers(token=token)
3374+ path = (
3375+ f"{self.endpoint}/api/kernels/{repo_id}"
3376+ if revision is None
3377+ else (f"{self.endpoint}/api/kernels/{repo_id}/revision/{quote(revision, safe='')}")
3378+ )
3379+ r = get_session().get(path, headers=headers, timeout=timeout)
3380+ hf_raise_for_status(r)
3381+ data = r.json()
3382+ return KernelInfo(**data)
3383+
32963384 @validate_hf_hub_args
32973385 def repo_info(
32983386 self,
@@ -3304,7 +3392,7 @@ def repo_info(
33043392 files_metadata: bool = False,
33053393 expand: ExpandModelProperty_T | ExpandDatasetProperty_T | ExpandSpaceProperty_T | None = None,
33063394 token: bool | str | None = None,
3307- ) -> ModelInfo | DatasetInfo | SpaceInfo:
3395+ ) -> ModelInfo | DatasetInfo | SpaceInfo | KernelInfo :
33083396 """
33093397 Get the info object for a given repo of a given type.
33103398
@@ -3354,6 +3442,9 @@ def repo_info(
33543442 method = self.dataset_info # type: ignore
33553443 case "space":
33563444 method = self.space_info # type: ignore
3445+ case "kernel":
3446+ # No expand/files_metadata for kernels
3447+ return self.kernel_info(repo_id, revision=revision, token=token, timeout=timeout)
33573448 case _:
33583449 raise ValueError("Unsupported repo type.")
33593450 return method(
@@ -3582,7 +3673,7 @@ def list_repo_tree(
35823673 revision (`str`, *optional*):
35833674 The revision of the repository from which to get the tree. Defaults to `"main"` branch.
35843675 repo_type (`str`, *optional*):
3585- The type of the repository from which to get the tree (`"model"`, `"dataset"` or `"space"` .
3676+ The type of the repository from which to get the tree (`"model"`, `"dataset"`, `"space"` or `"kernel"`) .
35863677 Defaults to `"model"`.
35873678 token (`bool` or `str`, *optional*):
35883679 A valid user access token (string). Defaults to the locally saved
@@ -3774,7 +3865,7 @@ def list_repo_refs(
37743865 A namespace (user or an organization) and a repo name separated
37753866 by a `/`.
37763867 repo_type (`str`, *optional*):
3777- Set to `"dataset"` or `"space "` if listing refs from a dataset or a Space ,
3868+ Set to `"dataset"`, `"space"` or `"kernel "` if listing refs from a dataset, a Space or a Kernel ,
37783869 `None` or `"model"` if listing from a model. Default is `None`.
37793870 include_pull_requests (`bool`, *optional*):
37803871 Whether to include refs from pull requests in the list. Defaults to `False`.
@@ -4277,7 +4368,7 @@ def create_repo(
42774368
42784369 path = f"{self.endpoint}/api/repos/create"
42794370
4280- if repo_type not in constants.REPO_TYPES :
4371+ if repo_type not in constants.REPO_TYPES_WITH_KERNEL :
42814372 raise ValueError("Invalid repo type")
42824373
42834374 resolved_visibility = _resolve_repo_visibility(private=private, visibility=visibility, repo_type=repo_type)
@@ -4310,7 +4401,7 @@ def create_repo(
43104401 ("space_volumes", "volumes", [v.to_dict() for v in space_volumes] if space_volumes else None),
43114402 ]
43124403
4313- if repo_type == "space" :
4404+ if repo_type == constants.REPO_TYPE_SPACE :
43144405 for _, key, value in space_args:
43154406 if value is not None:
43164407 payload[key] = value
@@ -4398,7 +4489,7 @@ def delete_repo(
43984489
43994490 path = f"{self.endpoint}/api/repos/delete"
44004491
4401- if repo_type not in constants.REPO_TYPES :
4492+ if repo_type not in constants.REPO_TYPES_WITH_KERNEL :
44024493 raise ValueError("Invalid repo type")
44034494
44044495 json = {"name": name, "organization": organization}
@@ -13474,6 +13565,8 @@ def get_local_safetensors_metadata(path: str | Path) -> SafetensorsRepoMetadata:
1347413565list_spaces = api.list_spaces
1347513566space_info = api.space_info
1347613567
13568+ kernel_info = api.kernel_info
13569+
1347713570list_papers = api.list_papers
1347813571paper_info = api.paper_info
1347913572read_paper = api.read_paper
0 commit comments