Skip to content

Commit

Permalink
Make sure create_repo respect organization privacy settings (#2679)
Browse files Browse the repository at this point in the history
* Make sure create_repo respect organization privacy settings

* update creds

* fix mocked tests

* Apply suggestions from code review

Co-authored-by: Célina <hanouticelina@gmail.com>

---------

Co-authored-by: Célina <hanouticelina@gmail.com>
  • Loading branch information
Wauplin and hanouticelina authored Nov 27, 2024
1 parent 7dc41b1 commit d0a948f
Show file tree
Hide file tree
Showing 9 changed files with 47 additions and 23 deletions.
4 changes: 2 additions & 2 deletions src/huggingface_hub/_commit_scheduler.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class CommitScheduler:
revision (`str`, *optional*):
The revision of the repo to commit to. Defaults to `main`.
private (`bool`, *optional*):
Whether to make the repo private. Defaults to `False`. This value is ignored if the repo already exist.
Whether to make the repo private. If `None` (default), the repo will be public unless the organization's default is private. This value is ignored if the repo already exists.
token (`str`, *optional*):
The token to use to commit to the repo. Defaults to the token saved on the machine.
allow_patterns (`List[str]` or `str`, *optional*):
Expand Down Expand Up @@ -106,7 +106,7 @@ def __init__(
path_in_repo: Optional[str] = None,
repo_type: Optional[str] = None,
revision: Optional[str] = None,
private: bool = False,
private: Optional[bool] = None,
token: Optional[str] = None,
allow_patterns: Optional[Union[List[str], str]] = None,
ignore_patterns: Optional[Union[List[str], str]] = None,
Expand Down
5 changes: 2 additions & 3 deletions src/huggingface_hub/_tensorboard_logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,7 @@ class HFSummaryWriter(SummaryWriter):
repo_revision (`str`, *optional*):
The revision of the repo to which the logs will be pushed. Defaults to "main".
repo_private (`bool`, *optional*):
Whether to create a private repo or not. Defaults to False. This argument is ignored if the repo already
exists.
Whether to make the repo private. If `None` (default), the repo will be public unless the organization's default is private. This value is ignored if the repo already exists.
path_in_repo (`str`, *optional*):
The path to the folder in the repo where the logs will be pushed. Defaults to "tensorboard/".
repo_allow_patterns (`List[str]` or `str`, *optional*):
Expand Down Expand Up @@ -137,7 +136,7 @@ def __init__(
squash_history: bool = False,
repo_type: Optional[str] = None,
repo_revision: Optional[str] = None,
repo_private: bool = False,
repo_private: Optional[bool] = None,
path_in_repo: Optional[str] = "tensorboard",
repo_allow_patterns: Optional[Union[List[str], str]] = "*.tfevents.*",
repo_ignore_patterns: Optional[Union[List[str], str]] = None,
Expand Down
2 changes: 1 addition & 1 deletion src/huggingface_hub/_upload_large_folder.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def upload_large_folder_internal(
*,
repo_type: str, # Repo type is required!
revision: Optional[str] = None,
private: bool = False,
private: Optional[bool] = None,
allow_patterns: Optional[Union[List[str], str]] = None,
ignore_patterns: Optional[Union[List[str], str]] = None,
num_workers: Optional[int] = None,
Expand Down
5 changes: 3 additions & 2 deletions src/huggingface_hub/fastai_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ def push_to_hub_fastai(
*,
repo_id: str,
commit_message: str = "Push FastAI model using huggingface_hub.",
private: bool = False,
private: Optional[bool] = None,
token: Optional[str] = None,
config: Optional[dict] = None,
branch: Optional[str] = None,
Expand All @@ -369,8 +369,9 @@ def push_to_hub_fastai(
The repository id for your model in Hub in the format of "namespace/repo_name". The namespace can be your individual account or an organization to which you have write access (for example, 'stanfordnlp/stanza-de').
commit_message (`str`, *optional*):
Message to commit while pushing. Will default to :obj:`"add model"`.
private (`bool`, *optional*, defaults to `False`):
private (`bool`, *optional*):
Whether or not the repository created should be private.
If `None` (default), will default to been public except if the organization's default is private.
token (`str`, *optional*):
The Hugging Face account token to use as HTTP bearer authorization for remote files. If :obj:`None`, the token will be asked by a prompt.
config (`dict`, *optional*):
Expand Down
15 changes: 9 additions & 6 deletions src/huggingface_hub/hf_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -3439,7 +3439,7 @@ def create_repo(
repo_id: str,
*,
token: Union[str, bool, None] = None,
private: bool = False,
private: Optional[bool] = None,
repo_type: Optional[str] = None,
exist_ok: bool = False,
resource_group_id: Optional[str] = None,
Expand All @@ -3461,8 +3461,8 @@ def create_repo(
token, which is the recommended method for authentication (see
https://huggingface.co/docs/huggingface_hub/quick-start#authentication).
To disable authentication, pass `False`.
private (`bool`, *optional*, defaults to `False`):
Whether the model repo should be private.
private (`bool`, *optional*):
Whether to make the repo private. If `None` (default), the repo will be public unless the organization's default is private. This value is ignored if the repo already exists.
repo_type (`str`, *optional*):
Set to `"dataset"` or `"space"` if uploading to a dataset or
space, `None` or `"model"` if uploading to a model. Default is
Expand Down Expand Up @@ -3503,7 +3503,9 @@ def create_repo(
if repo_type not in constants.REPO_TYPES:
raise ValueError("Invalid repo type")

json: Dict[str, Any] = {"name": name, "organization": organization, "private": private}
json: Dict[str, Any] = {"name": name, "organization": organization}
if private is not None:
json["private"] = private
if repo_type is not None:
json["type"] = repo_type
if repo_type == "space":
Expand Down Expand Up @@ -5017,7 +5019,7 @@ def upload_large_folder(
*,
repo_type: str, # Repo type is required!
revision: Optional[str] = None,
private: bool = False,
private: Optional[bool] = None,
allow_patterns: Optional[Union[List[str], str]] = None,
ignore_patterns: Optional[Union[List[str], str]] = None,
num_workers: Optional[int] = None,
Expand Down Expand Up @@ -5045,7 +5047,8 @@ def upload_large_folder(
revision (`str`, `optional`):
The branch to commit to. If not provided, the `main` branch will be used.
private (`bool`, `optional`):
Whether the repository should be private. Defaults to False.
Whether the repository should be private.
If `None` (default), the repo will be public unless the organization's default is private.
allow_patterns (`List[str]` or `str`, *optional*):
If provided, only files matching at least one pattern are uploaded.
ignore_patterns (`List[str]` or `str`, *optional*):
Expand Down
5 changes: 3 additions & 2 deletions src/huggingface_hub/hub_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -620,7 +620,7 @@ def push_to_hub(
*,
config: Optional[Union[dict, "DataclassInstance"]] = None,
commit_message: str = "Push model using huggingface_hub.",
private: bool = False,
private: Optional[bool] = None,
token: Optional[str] = None,
branch: Optional[str] = None,
create_pr: Optional[bool] = None,
Expand All @@ -643,8 +643,9 @@ def push_to_hub(
Model configuration specified as a key/value dictionary or a dataclass instance.
commit_message (`str`, *optional*):
Message to commit while pushing.
private (`bool`, *optional*, defaults to `False`):
private (`bool`, *optional*):
Whether the repository created should be private.
If `None` (default), the repo will be public unless the organization's default is private.
token (`str`, *optional*):
The token to use as HTTP bearer authorization for remote files. By default, it will use the token
cached when running `huggingface-cli login`.
Expand Down
5 changes: 3 additions & 2 deletions src/huggingface_hub/keras_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ def push_to_hub_keras(
*,
config: Optional[dict] = None,
commit_message: str = "Push Keras model using huggingface_hub.",
private: bool = False,
private: Optional[bool] = None,
api_endpoint: Optional[str] = None,
token: Optional[str] = None,
branch: Optional[str] = None,
Expand Down Expand Up @@ -330,8 +330,9 @@ def push_to_hub_keras(
ID of the repository to push to (example: `"username/my-model"`).
commit_message (`str`, *optional*, defaults to "Add Keras model"):
Message to commit while pushing.
private (`bool`, *optional*, defaults to `False`):
private (`bool`, *optional*):
Whether the repository created should be private.
If `None` (default), the repo will be public unless the organization's default is private.
api_endpoint (`str`, *optional*):
The API endpoint to use when pushing the model to the hub.
token (`str`, *optional*):
Expand Down
24 changes: 19 additions & 5 deletions tests/test_hf_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,16 @@
)
from huggingface_hub.utils.endpoint_helpers import _is_emission_within_threshold

from .testing_constants import ENDPOINT_STAGING, FULL_NAME, OTHER_TOKEN, OTHER_USER, TOKEN, USER
from .testing_constants import (
ENDPOINT_STAGING,
ENTERPRISE_ORG,
ENTERPRISE_TOKEN,
FULL_NAME,
OTHER_TOKEN,
OTHER_USER,
TOKEN,
USER,
)
from .testing_utils import (
DUMMY_DATASET_ID,
DUMMY_DATASET_ID_REVISION_ONE_SPECIFIC_COMMIT,
Expand Down Expand Up @@ -455,6 +464,15 @@ def test_create_repo_already_exists_but_no_write_permission(self):
# Clean up
self._api.delete_repo(repo_id=repo_id, token=OTHER_TOKEN)

def test_create_repo_private_by_default(self):
"""Enterprise Hub allows creating private repos by default. Let's test that."""
repo_id = f"{ENTERPRISE_ORG}/{repo_name()}"
self._api.create_repo(repo_id, token=ENTERPRISE_TOKEN)
info = self._api.model_info(repo_id, token=ENTERPRISE_TOKEN, expand="private")
assert info.private

self._api.delete_repo(repo_id, token=ENTERPRISE_TOKEN)

@use_tmp_repo()
def test_upload_file_create_pr(self, repo_url: RepoUrl) -> None:
repo_id = repo_url.repo_id
Expand Down Expand Up @@ -3393,7 +3411,6 @@ def test_create_space_with_hardware(self) -> None:
json={
"name": self.repo_id,
"organization": None,
"private": False,
"type": "space",
"sdk": "gradio",
"hardware": "t4-medium",
Expand All @@ -3414,7 +3431,6 @@ def test_create_space_with_hardware_and_sleep_time(self) -> None:
json={
"name": self.repo_id,
"organization": None,
"private": False,
"type": "space",
"sdk": "gradio",
"hardware": "t4-medium",
Expand All @@ -3435,7 +3451,6 @@ def test_create_space_with_storage(self) -> None:
json={
"name": self.repo_id,
"organization": None,
"private": False,
"type": "space",
"sdk": "gradio",
"storageTier": "large",
Expand All @@ -3462,7 +3477,6 @@ def test_create_space_with_secrets_and_variables(self) -> None:
json={
"name": self.repo_id,
"organization": None,
"private": False,
"type": "space",
"sdk": "gradio",
"secrets": [
Expand Down
5 changes: 5 additions & 0 deletions tests/testing_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@
OTHER_USER = "DVUser"
OTHER_TOKEN = "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"

# Used to test enterprise features, typically creating private repos by default
ENTERPRISE_USER = "EnterpriseAdmin"
ENTERPRISE_ORG = "EnterpriseOrgPrivate"
ENTERPRISE_TOKEN = "hf_enterprise_admin_token"

ENDPOINT_PRODUCTION = "https://huggingface.co"
ENDPOINT_STAGING = "https://hub-ci.huggingface.co"

Expand Down

0 comments on commit d0a948f

Please sign in to comment.