Skip to content

Commit d0a948f

Browse files
Make sure create_repo respect organization privacy settings (#2679)
* 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>
1 parent 7dc41b1 commit d0a948f

File tree

9 files changed

+47
-23
lines changed

9 files changed

+47
-23
lines changed

src/huggingface_hub/_commit_scheduler.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ class CommitScheduler:
5050
revision (`str`, *optional*):
5151
The revision of the repo to commit to. Defaults to `main`.
5252
private (`bool`, *optional*):
53-
Whether to make the repo private. Defaults to `False`. This value is ignored if the repo already exist.
53+
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.
5454
token (`str`, *optional*):
5555
The token to use to commit to the repo. Defaults to the token saved on the machine.
5656
allow_patterns (`List[str]` or `str`, *optional*):
@@ -106,7 +106,7 @@ def __init__(
106106
path_in_repo: Optional[str] = None,
107107
repo_type: Optional[str] = None,
108108
revision: Optional[str] = None,
109-
private: bool = False,
109+
private: Optional[bool] = None,
110110
token: Optional[str] = None,
111111
allow_patterns: Optional[Union[List[str], str]] = None,
112112
ignore_patterns: Optional[Union[List[str], str]] = None,

src/huggingface_hub/_tensorboard_logger.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,7 @@ class HFSummaryWriter(SummaryWriter):
7575
repo_revision (`str`, *optional*):
7676
The revision of the repo to which the logs will be pushed. Defaults to "main".
7777
repo_private (`bool`, *optional*):
78-
Whether to create a private repo or not. Defaults to False. This argument is ignored if the repo already
79-
exists.
78+
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.
8079
path_in_repo (`str`, *optional*):
8180
The path to the folder in the repo where the logs will be pushed. Defaults to "tensorboard/".
8281
repo_allow_patterns (`List[str]` or `str`, *optional*):
@@ -137,7 +136,7 @@ def __init__(
137136
squash_history: bool = False,
138137
repo_type: Optional[str] = None,
139138
repo_revision: Optional[str] = None,
140-
repo_private: bool = False,
139+
repo_private: Optional[bool] = None,
141140
path_in_repo: Optional[str] = "tensorboard",
142141
repo_allow_patterns: Optional[Union[List[str], str]] = "*.tfevents.*",
143142
repo_ignore_patterns: Optional[Union[List[str], str]] = None,

src/huggingface_hub/_upload_large_folder.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def upload_large_folder_internal(
5252
*,
5353
repo_type: str, # Repo type is required!
5454
revision: Optional[str] = None,
55-
private: bool = False,
55+
private: Optional[bool] = None,
5656
allow_patterns: Optional[Union[List[str], str]] = None,
5757
ignore_patterns: Optional[Union[List[str], str]] = None,
5858
num_workers: Optional[int] = None,

src/huggingface_hub/fastai_utils.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,7 @@ def push_to_hub_fastai(
345345
*,
346346
repo_id: str,
347347
commit_message: str = "Push FastAI model using huggingface_hub.",
348-
private: bool = False,
348+
private: Optional[bool] = None,
349349
token: Optional[str] = None,
350350
config: Optional[dict] = None,
351351
branch: Optional[str] = None,
@@ -369,8 +369,9 @@ def push_to_hub_fastai(
369369
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').
370370
commit_message (`str`, *optional*):
371371
Message to commit while pushing. Will default to :obj:`"add model"`.
372-
private (`bool`, *optional*, defaults to `False`):
372+
private (`bool`, *optional*):
373373
Whether or not the repository created should be private.
374+
If `None` (default), will default to been public except if the organization's default is private.
374375
token (`str`, *optional*):
375376
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.
376377
config (`dict`, *optional*):

src/huggingface_hub/hf_api.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3439,7 +3439,7 @@ def create_repo(
34393439
repo_id: str,
34403440
*,
34413441
token: Union[str, bool, None] = None,
3442-
private: bool = False,
3442+
private: Optional[bool] = None,
34433443
repo_type: Optional[str] = None,
34443444
exist_ok: bool = False,
34453445
resource_group_id: Optional[str] = None,
@@ -3461,8 +3461,8 @@ def create_repo(
34613461
token, which is the recommended method for authentication (see
34623462
https://huggingface.co/docs/huggingface_hub/quick-start#authentication).
34633463
To disable authentication, pass `False`.
3464-
private (`bool`, *optional*, defaults to `False`):
3465-
Whether the model repo should be private.
3464+
private (`bool`, *optional*):
3465+
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.
34663466
repo_type (`str`, *optional*):
34673467
Set to `"dataset"` or `"space"` if uploading to a dataset or
34683468
space, `None` or `"model"` if uploading to a model. Default is
@@ -3503,7 +3503,9 @@ def create_repo(
35033503
if repo_type not in constants.REPO_TYPES:
35043504
raise ValueError("Invalid repo type")
35053505

3506-
json: Dict[str, Any] = {"name": name, "organization": organization, "private": private}
3506+
json: Dict[str, Any] = {"name": name, "organization": organization}
3507+
if private is not None:
3508+
json["private"] = private
35073509
if repo_type is not None:
35083510
json["type"] = repo_type
35093511
if repo_type == "space":
@@ -5017,7 +5019,7 @@ def upload_large_folder(
50175019
*,
50185020
repo_type: str, # Repo type is required!
50195021
revision: Optional[str] = None,
5020-
private: bool = False,
5022+
private: Optional[bool] = None,
50215023
allow_patterns: Optional[Union[List[str], str]] = None,
50225024
ignore_patterns: Optional[Union[List[str], str]] = None,
50235025
num_workers: Optional[int] = None,
@@ -5045,7 +5047,8 @@ def upload_large_folder(
50455047
revision (`str`, `optional`):
50465048
The branch to commit to. If not provided, the `main` branch will be used.
50475049
private (`bool`, `optional`):
5048-
Whether the repository should be private. Defaults to False.
5050+
Whether the repository should be private.
5051+
If `None` (default), the repo will be public unless the organization's default is private.
50495052
allow_patterns (`List[str]` or `str`, *optional*):
50505053
If provided, only files matching at least one pattern are uploaded.
50515054
ignore_patterns (`List[str]` or `str`, *optional*):

src/huggingface_hub/hub_mixin.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -620,7 +620,7 @@ def push_to_hub(
620620
*,
621621
config: Optional[Union[dict, "DataclassInstance"]] = None,
622622
commit_message: str = "Push model using huggingface_hub.",
623-
private: bool = False,
623+
private: Optional[bool] = None,
624624
token: Optional[str] = None,
625625
branch: Optional[str] = None,
626626
create_pr: Optional[bool] = None,
@@ -643,8 +643,9 @@ def push_to_hub(
643643
Model configuration specified as a key/value dictionary or a dataclass instance.
644644
commit_message (`str`, *optional*):
645645
Message to commit while pushing.
646-
private (`bool`, *optional*, defaults to `False`):
646+
private (`bool`, *optional*):
647647
Whether the repository created should be private.
648+
If `None` (default), the repo will be public unless the organization's default is private.
648649
token (`str`, *optional*):
649650
The token to use as HTTP bearer authorization for remote files. By default, it will use the token
650651
cached when running `huggingface-cli login`.

src/huggingface_hub/keras_mixin.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ def push_to_hub_keras(
301301
*,
302302
config: Optional[dict] = None,
303303
commit_message: str = "Push Keras model using huggingface_hub.",
304-
private: bool = False,
304+
private: Optional[bool] = None,
305305
api_endpoint: Optional[str] = None,
306306
token: Optional[str] = None,
307307
branch: Optional[str] = None,
@@ -330,8 +330,9 @@ def push_to_hub_keras(
330330
ID of the repository to push to (example: `"username/my-model"`).
331331
commit_message (`str`, *optional*, defaults to "Add Keras model"):
332332
Message to commit while pushing.
333-
private (`bool`, *optional*, defaults to `False`):
333+
private (`bool`, *optional*):
334334
Whether the repository created should be private.
335+
If `None` (default), the repo will be public unless the organization's default is private.
335336
api_endpoint (`str`, *optional*):
336337
The API endpoint to use when pushing the model to the hub.
337338
token (`str`, *optional*):

tests/test_hf_api.py

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,16 @@
8484
)
8585
from huggingface_hub.utils.endpoint_helpers import _is_emission_within_threshold
8686

87-
from .testing_constants import ENDPOINT_STAGING, FULL_NAME, OTHER_TOKEN, OTHER_USER, TOKEN, USER
87+
from .testing_constants import (
88+
ENDPOINT_STAGING,
89+
ENTERPRISE_ORG,
90+
ENTERPRISE_TOKEN,
91+
FULL_NAME,
92+
OTHER_TOKEN,
93+
OTHER_USER,
94+
TOKEN,
95+
USER,
96+
)
8897
from .testing_utils import (
8998
DUMMY_DATASET_ID,
9099
DUMMY_DATASET_ID_REVISION_ONE_SPECIFIC_COMMIT,
@@ -455,6 +464,15 @@ def test_create_repo_already_exists_but_no_write_permission(self):
455464
# Clean up
456465
self._api.delete_repo(repo_id=repo_id, token=OTHER_TOKEN)
457466

467+
def test_create_repo_private_by_default(self):
468+
"""Enterprise Hub allows creating private repos by default. Let's test that."""
469+
repo_id = f"{ENTERPRISE_ORG}/{repo_name()}"
470+
self._api.create_repo(repo_id, token=ENTERPRISE_TOKEN)
471+
info = self._api.model_info(repo_id, token=ENTERPRISE_TOKEN, expand="private")
472+
assert info.private
473+
474+
self._api.delete_repo(repo_id, token=ENTERPRISE_TOKEN)
475+
458476
@use_tmp_repo()
459477
def test_upload_file_create_pr(self, repo_url: RepoUrl) -> None:
460478
repo_id = repo_url.repo_id
@@ -3393,7 +3411,6 @@ def test_create_space_with_hardware(self) -> None:
33933411
json={
33943412
"name": self.repo_id,
33953413
"organization": None,
3396-
"private": False,
33973414
"type": "space",
33983415
"sdk": "gradio",
33993416
"hardware": "t4-medium",
@@ -3414,7 +3431,6 @@ def test_create_space_with_hardware_and_sleep_time(self) -> None:
34143431
json={
34153432
"name": self.repo_id,
34163433
"organization": None,
3417-
"private": False,
34183434
"type": "space",
34193435
"sdk": "gradio",
34203436
"hardware": "t4-medium",
@@ -3435,7 +3451,6 @@ def test_create_space_with_storage(self) -> None:
34353451
json={
34363452
"name": self.repo_id,
34373453
"organization": None,
3438-
"private": False,
34393454
"type": "space",
34403455
"sdk": "gradio",
34413456
"storageTier": "large",
@@ -3462,7 +3477,6 @@ def test_create_space_with_secrets_and_variables(self) -> None:
34623477
json={
34633478
"name": self.repo_id,
34643479
"organization": None,
3465-
"private": False,
34663480
"type": "space",
34673481
"sdk": "gradio",
34683482
"secrets": [

tests/testing_constants.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@
1010
OTHER_USER = "DVUser"
1111
OTHER_TOKEN = "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"
1212

13+
# Used to test enterprise features, typically creating private repos by default
14+
ENTERPRISE_USER = "EnterpriseAdmin"
15+
ENTERPRISE_ORG = "EnterpriseOrgPrivate"
16+
ENTERPRISE_TOKEN = "hf_enterprise_admin_token"
17+
1318
ENDPOINT_PRODUCTION = "https://huggingface.co"
1419
ENDPOINT_STAGING = "https://hub-ci.huggingface.co"
1520

0 commit comments

Comments
 (0)