Skip to content

Commit 1766706

Browse files
authored
πŸ§‘β€πŸ’» Add aliases for repo names (#128)
1 parent 642f70e commit 1766706

16 files changed

+167
-40
lines changed

β€ŽREADME.md

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,19 +55,19 @@ You can run our packages with vanilla JS, without any bundler, by using a CDN or
5555
## Usage example
5656

5757
```ts
58-
import { createRepo, uploadFile } from "@huggingface/hub";
58+
import { createRepo, uploadFile, deleteFiles } from "@huggingface/hub";
5959
import { HfInference } from "@huggingface/inference";
6060

6161
// use an access token from your free account
6262
const HF_ACCESS_TOKEN = "hf_...";
6363

6464
await createRepo({
65-
repo: {type: "model", name: "my-user/nlp-test"},
65+
repo: "my-user/nlp-model", // or {type: "model", name: "my-user/nlp-test"},
6666
credentials: {accessToken: HF_ACCESS_TOKEN}
6767
});
6868

6969
await uploadFile({
70-
repo: {type: "model", name: "my-user/nlp-test"},
70+
repo: "my-user/nlp-model",
7171
credentials: {accessToken: HF_ACCESS_TOKEN},
7272
// Can work with native File in browsers
7373
file: {
@@ -76,6 +76,12 @@ await uploadFile({
7676
}
7777
});
7878

79+
await deleteFiles({
80+
repo: {type: "space", name: "my-user/my-space"}, // or "spaces/my-user/my-space"
81+
credentials: {accessToken: HF_ACCESS_TOKEN},
82+
paths: ["README.md", ".gitattributes"]
83+
});
84+
7985
const inference = new HfInference(HF_ACCESS_TOKEN);
8086

8187
await inference.translation({

β€Žpackages/hub/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ For some of the calls, you need to create an account and generate an [access tok
1414

1515
```ts
1616
import { createRepo, uploadFiles, deleteFile, deleteRepo, listFiles, whoAmI } from "@huggingface/hub";
17-
import type { RepoId, Credentials } from "@huggingface/hub";
17+
import type { RepoDesignation, Credentials } from "@huggingface/hub";
1818

19-
const repo: RepoId = { type: "model", name: "myname/some-model" };
19+
const repo: RepoDesignation = { type: "model", name: "myname/some-model" };
2020
const credentials: Credentials = { accessToken: "hf_..." };
2121

2222
const {name: username} = await whoAmI({credentials});

β€Žpackages/hub/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ export type {
55
AccessTokenRole,
66
AuthType,
77
Credentials,
8+
RepoDesignation,
9+
RepoFullName,
810
RepoId,
911
RepoType,
1012
SpaceHardwareFlavor,

β€Žpackages/hub/src/lib/commit.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,15 @@ import type {
1010
ApiPreuploadRequest,
1111
ApiPreuploadResponse,
1212
} from "../types/api/api-commit";
13-
import type { Credentials, RepoId } from "../types/public";
13+
import type { Credentials, RepoDesignation } from "../types/public";
1414
import { base64FromBytes } from "../utils/base64FromBytes";
1515
import { checkCredentials } from "../utils/checkCredentials";
1616
import { chunk } from "../utils/chunk";
1717
import { isFrontend } from "../utils/env-predicates";
1818
import { promisesQueue } from "../utils/promisesQueue";
1919
import { promisesQueueStreaming } from "../utils/promisesQueueStreaming";
2020
import { sha256 } from "../utils/sha256";
21+
import { toRepoId } from "../utils/toRepoId";
2122
import { WebBlob } from "../utils/WebBlob";
2223

2324
const CONCURRENT_SHAS = 5;
@@ -54,7 +55,7 @@ type CommitBlobOperation = Exclude<CommitOperation, CommitFile> | CommitBlob;
5455
export interface CommitParams {
5556
title: string;
5657
description?: string;
57-
repo: RepoId;
58+
repo: RepoDesignation;
5859
operations: CommitOperation[];
5960
credentials: Credentials;
6061
/** @default "main" */
@@ -124,6 +125,7 @@ async function createBlob(url: URL): Promise<Blob> {
124125
*/
125126
async function* commitIter(params: CommitParams): AsyncGenerator<unknown, CommitOutput> {
126127
checkCredentials(params.credentials);
128+
const repoId = toRepoId(params.repo);
127129
yield "preuploading";
128130

129131
const lfsShas = new Map<string, string | null>();
@@ -163,7 +165,7 @@ async function* commitIter(params: CommitParams): AsyncGenerator<unknown, Commit
163165
};
164166

165167
const res = await fetch(
166-
`${params.hubUrl ?? HUB_URL}/api/${params.repo.type}s/${params.repo.name}/preupload/${encodeURIComponent(
168+
`${params.hubUrl ?? HUB_URL}/api/${repoId.type}s/${repoId.name}/preupload/${encodeURIComponent(
167169
params.branch ?? "main"
168170
)}` + (params.isPullRequest ? "?create_pr=1" : ""),
169171
{
@@ -221,8 +223,8 @@ async function* commitIter(params: CommitParams): AsyncGenerator<unknown, Commit
221223
};
222224

223225
const res = await fetch(
224-
`${params.hubUrl ?? HUB_URL}/${params.repo.type === "model" ? "" : params.repo.type + "s/"}${
225-
params.repo.name
226+
`${params.hubUrl ?? HUB_URL}/${repoId.type === "model" ? "" : repoId.type + "s/"}${
227+
repoId.name
226228
}.git/info/lfs/objects/batch`,
227229
{
228230
method: "POST",
@@ -355,7 +357,7 @@ async function* commitIter(params: CommitParams): AsyncGenerator<unknown, Commit
355357
yield "committing";
356358

357359
const res = await fetch(
358-
`${params.hubUrl ?? HUB_URL}/api/${params.repo.type}s/${params.repo.name}/commit/${encodeURIComponent(
360+
`${params.hubUrl ?? HUB_URL}/api/${repoId.type}s/${repoId.name}/commit/${encodeURIComponent(
359361
params.branch ?? "main"
360362
)}` + (params.isPullRequest ? "?create_pr=1" : ""),
361363
{

β€Žpackages/hub/src/lib/create-repo.spec.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,49 @@ describe("createRepo", () => {
5353

5454
await expect(tryCreate).rejects.toBeInstanceOf(TypeError);
5555
});
56+
57+
it("should create a model with a string as name", async () => {
58+
const repoName = `${TEST_USER}/TEST-${insecureRandomString()}`;
59+
60+
const result = await createRepo({
61+
credentials: {
62+
accessToken: TEST_ACCESS_TOKEN,
63+
},
64+
repo: repoName,
65+
files: [{ path: ".gitattributes", content: new Blob(["*.html filter=lfs diff=lfs merge=lfs -text"]) }],
66+
});
67+
68+
assert.deepStrictEqual(result, {
69+
repoUrl: `${HUB_URL}/${repoName}`,
70+
});
71+
72+
await deleteRepo({
73+
repo: {
74+
name: repoName,
75+
type: "model",
76+
},
77+
credentials: { accessToken: TEST_ACCESS_TOKEN },
78+
});
79+
});
80+
81+
it("should create a dataset with a string as name", async () => {
82+
const repoName = `datasets/${TEST_USER}/TEST-${insecureRandomString()}`;
83+
84+
const result = await createRepo({
85+
credentials: {
86+
accessToken: TEST_ACCESS_TOKEN,
87+
},
88+
repo: repoName,
89+
files: [{ path: ".gitattributes", content: new Blob(["*.html filter=lfs diff=lfs merge=lfs -text"]) }],
90+
});
91+
92+
assert.deepStrictEqual(result, {
93+
repoUrl: `${HUB_URL}/${repoName}`,
94+
});
95+
96+
await deleteRepo({
97+
repo: repoName,
98+
credentials: { accessToken: TEST_ACCESS_TOKEN },
99+
});
100+
});
56101
});

β€Žpackages/hub/src/lib/create-repo.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import { HUB_URL } from "../consts";
22
import { createApiError } from "../error";
33
import type { ApiCreateRepoPayload } from "../types/api/api-create-repo";
4-
import type { Credentials, RepoId, SpaceSdk } from "../types/public";
4+
import type { Credentials, RepoDesignation, SpaceSdk } from "../types/public";
55
import { base64FromBytes } from "../utils/base64FromBytes";
66
import { checkCredentials } from "../utils/checkCredentials";
7+
import { toRepoId } from "../utils/toRepoId";
78

89
export async function createRepo(params: {
9-
repo: RepoId;
10+
repo: RepoDesignation;
1011
credentials: Credentials;
1112
private?: boolean;
1213
license?: string;
@@ -19,11 +20,12 @@ export async function createRepo(params: {
1920
hubUrl?: string;
2021
}): Promise<{ repoUrl: string }> {
2122
checkCredentials(params.credentials);
22-
const [namespace, repoName] = params.repo.name.split("/");
23+
const repoId = toRepoId(params.repo);
24+
const [namespace, repoName] = repoId.name.split("/");
2325

2426
if (!namespace || !repoName) {
2527
throw new TypeError(
26-
`"${params.repo.name}" is not a fully qualified repo name. It should be of the form "{namespace}/{repoName}".`
28+
`"${repoId.name}" is not a fully qualified repo name. It should be of the form "{namespace}/{repoName}".`
2729
);
2830
}
2931

@@ -34,13 +36,13 @@ export async function createRepo(params: {
3436
private: params.private,
3537
organization: namespace,
3638
license: params.license,
37-
...(params.repo.type === "space"
39+
...(repoId.type === "space"
3840
? {
3941
type: "space",
4042
sdk: "static",
4143
}
4244
: {
43-
type: params.repo.type,
45+
type: repoId.type,
4446
}),
4547
files: params.files
4648
? await Promise.all(

β€Žpackages/hub/src/lib/delete-repo.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,24 @@
11
import { HUB_URL } from "../consts";
22
import { createApiError } from "../error";
3-
import type { Credentials, RepoId } from "../types/public";
3+
import type { Credentials, RepoDesignation } from "../types/public";
44
import { checkCredentials } from "../utils/checkCredentials";
5+
import { toRepoId } from "../utils/toRepoId";
56

6-
export async function deleteRepo(params: { repo: RepoId; credentials: Credentials; hubUrl?: string }): Promise<void> {
7+
export async function deleteRepo(params: {
8+
repo: RepoDesignation;
9+
credentials: Credentials;
10+
hubUrl?: string;
11+
}): Promise<void> {
712
checkCredentials(params.credentials);
8-
const [namespace, repoName] = params.repo.name.split("/");
13+
const repoId = toRepoId(params.repo);
14+
const [namespace, repoName] = repoId.name.split("/");
915

1016
const res = await fetch(`${params.hubUrl ?? HUB_URL}/api/repos/delete`, {
1117
method: "DELETE",
1218
body: JSON.stringify({
1319
name: repoName,
1420
organization: namespace,
15-
type: params.repo.type,
21+
type: repoId.type,
1622
}),
1723
headers: {
1824
Authorization: `Bearer ${params.credentials.accessToken}`,

β€Žpackages/hub/src/lib/deleteFile.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import type { Credentials, RepoId } from "../types/public";
1+
import type { Credentials } from "../types/public";
22
import type { CommitOutput, CommitParams } from "./commit";
33
import { commit } from "./commit";
44

55
export function deleteFile(params: {
66
credentials: Credentials;
7-
repo: RepoId;
7+
repo: CommitParams["repo"];
88
path: string;
99
commitTitle?: CommitParams["title"];
1010
commitDescription?: CommitParams["description"];

β€Žpackages/hub/src/lib/deleteFiles.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import type { Credentials, RepoId } from "../types/public";
1+
import type { Credentials } from "../types/public";
22
import type { CommitOutput, CommitParams } from "./commit";
33
import { commit } from "./commit";
44

55
export function deleteFiles(params: {
66
credentials: Credentials;
7-
repo: RepoId;
7+
repo: CommitParams["repo"];
88
paths: string[];
99
commitTitle?: CommitParams["title"];
1010
commitDescription?: CommitParams["description"];

β€Žpackages/hub/src/lib/download-file.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import { HUB_URL } from "../consts";
22
import { createApiError } from "../error";
3-
import type { Credentials, RepoId } from "../types/public";
3+
import type { Credentials, RepoDesignation } from "../types/public";
44
import { checkCredentials } from "../utils/checkCredentials";
5+
import { toRepoId } from "../utils/toRepoId";
56

67
/**
78
* @returns null when the file doesn't exist
89
*/
910
export async function downloadFile(params: {
10-
repo: RepoId;
11+
repo: RepoDesignation;
1112
path: string;
1213
/**
1314
* If true, will download the raw git file.
@@ -20,9 +21,10 @@ export async function downloadFile(params: {
2021
hubUrl?: string;
2122
}): Promise<Response | null> {
2223
checkCredentials(params.credentials);
23-
const url = `${params.hubUrl ?? HUB_URL}/${params.repo.type === "model" ? "" : `${params.repo.type}s/`}${
24-
params.repo.name
25-
}/${params.raw ? "raw" : "resolve"}/${encodeURIComponent(params.revision ?? "main")}/${params.path}`;
24+
const repoId = toRepoId(params.repo);
25+
const url = `${params.hubUrl ?? HUB_URL}/${repoId.type === "model" ? "" : `${repoId.type}s/`}${repoId.name}/${
26+
params.raw ? "raw" : "resolve"
27+
}/${encodeURIComponent(params.revision ?? "main")}/${params.path}`;
2628

2729
const resp = await fetch(url, {
2830
headers: params.credentials

0 commit comments

Comments
Β (0)