Skip to content

Commit 4e78faf

Browse files
authored
Use xet token provided by server to save API calls (#1854)
cc @assafvayner for viz , @Kakulukian too https://huggingface.slack.com/archives/C035N5UE2JU/p1763991238834179
1 parent c62c9b3 commit 4e78faf

File tree

11 files changed

+64
-52
lines changed

11 files changed

+64
-52
lines changed

packages/hub/src/lib/collection-info.spec.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ describe("collectionInfo", () => {
103103
lastModified: "2023-04-01T15:29:38.000Z",
104104
likes: expect.any(Number),
105105
pinned: false,
106+
featured: false,
106107
position: 2,
107108
private: false,
108109
repoType: "space",

packages/hub/src/lib/commit.ts

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import { eventToGenerator } from "../utils/eventToGenerator";
2222
import { base64FromBytes } from "../utils/base64FromBytes";
2323
import { isFrontend } from "../utils/isFrontend";
2424
import { createBlobs } from "../utils/createBlobs";
25+
import type { XetTokenParams } from "../utils/uploadShards";
2526
import { uploadShards } from "../utils/uploadShards";
2627
import { splitAsyncGenerator } from "../utils/splitAsyncGenerator";
2728
import { SplicedBlob } from "../utils/SplicedBlob";
@@ -350,8 +351,8 @@ export async function* commitIter(params: CommitParams): AsyncGenerator<CommitPr
350351
if (useXet && json.transfer !== "xet") {
351352
useXet = false;
352353
}
353-
let xetRefreshWriteTokenUrl: string | undefined;
354-
let xetSessionId: string | undefined;
354+
355+
let xetParams: XetTokenParams | null = null;
355356

356357
if (useXet) {
357358
// First get all the files that are already uploaded out of the way
@@ -377,16 +378,17 @@ export async function* commitIter(params: CommitParams): AsyncGenerator<CommitPr
377378
state: "uploading",
378379
};
379380
} else {
380-
xetRefreshWriteTokenUrl = obj.actions.upload.href;
381-
// Also, obj.actions.upload.header: {
382-
// X-Xet-Cas-Url: string;
383-
// X-Xet-Access-Token: string;
384-
// X-Xet-Token-Expiration: string;
385-
// X-Xet-Session-Id: string;
386-
// }
387381
const headers = new Headers(obj.actions.upload.header);
388-
xetSessionId = headers.get("X-Xet-Session-Id") ?? undefined;
389-
// todo: use other data, like x-xet-cas-url, ...
382+
383+
xetParams = {
384+
sessionId: headers.get("X-Xet-Session-Id") ?? undefined,
385+
casUrl: headers.get("X-Xet-Cas-Url") ?? undefined,
386+
accessToken: headers.get("X-Xet-Access-Token") ?? undefined,
387+
expiresAt: headers.get("X-Xet-Token-Expiration")
388+
? new Date(parseInt(headers.get("X-Xet-Token-Expiration") ?? "0") * 1000)
389+
: undefined,
390+
refreshWriteTokenUrl: obj.actions.upload.href,
391+
};
390392
}
391393
}
392394
const source = (async function* () {
@@ -399,8 +401,8 @@ export async function* commitIter(params: CommitParams): AsyncGenerator<CommitPr
399401
yield { content: op.content, path: op.path, sha256: obj.oid };
400402
}
401403
})();
402-
if (xetRefreshWriteTokenUrl) {
403-
const xetRefreshWriteTokenUrlFixed = xetRefreshWriteTokenUrl;
404+
if (xetParams) {
405+
const fixedXetParams = xetParams;
404406
const sources = splitAsyncGenerator(source, 5);
405407
yield* eventToGenerator((yieldCallback, returnCallback, rejectCallback) =>
406408
Promise.all(
@@ -410,21 +412,19 @@ export async function* commitIter(params: CommitParams): AsyncGenerator<CommitPr
410412
accessToken,
411413
hubUrl: params.hubUrl ?? HUB_URL,
412414
repo: repoId,
413-
xetRefreshWriteTokenUrl: xetRefreshWriteTokenUrlFixed,
414-
xetSessionId,
415+
xetParams: fixedXetParams,
415416
// todo: maybe leave empty if PR?
416417
rev: params.branch ?? "main",
417418
isPullRequest: params.isPullRequest,
418419
yieldCallback: (event) => yieldCallback({ ...event, state: "uploading" }),
419420
})) {
420421
if (event.event === "file") {
421-
// No need: uploading xorbs already sent a fileProgress event with progress 1
422-
// yieldCallback({
423-
// event: "fileProgress" as const,
424-
// path: event.path,
425-
// progress: 1,
426-
// state: "uploading" as const,
427-
// });
422+
yieldCallback({
423+
event: "fileProgress" as const,
424+
path: event.path,
425+
progress: 1,
426+
state: "uploading" as const,
427+
});
428428
} else if (event.event === "fileProgress") {
429429
yieldCallback({
430430
event: "fileProgress" as const,

packages/hub/src/lib/list-collections.spec.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ describe("listCollections", () => {
115115
pinned: false,
116116
position: 2,
117117
private: false,
118+
featured: false,
118119
repoType: "space",
119120
runtime: {
120121
hardware: {

packages/hub/src/lib/upload-files-with-progress.spec.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,9 @@ describe("uploadFilesWithProgress", () => {
7070
// assert(intermediateUploadEvents.length > 0, "There should be at least one intermediate upload event");
7171
// }
7272
progressEvents = progressEvents.filter(
73-
(e) => e.event !== "fileProgress" || e.progress === 0 || e.progress === 1
73+
(e, i) =>
74+
(e.event !== "fileProgress" || e.progress === 0 || e.progress === 1) &&
75+
(i === 0 || JSON.stringify(e) !== JSON.stringify(progressEvents[i - 1]))
7476
);
7577

7678
assert.deepStrictEqual(progressEvents, [

packages/hub/src/lib/who-am-i.spec.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ describe("whoAmI", () => {
2121
isPro: false,
2222
periodEnd: null,
2323
avatarUrl: "/avatars/934b830e9fdaa879487852f79eef7165.svg",
24+
billingMode: "postpaid",
2425
orgs: [],
2526
auth: {
2627
type: "access_token",

packages/hub/src/lib/who-am-i.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export interface WhoAmIUser {
2020
* Unix timestamp in seconds
2121
*/
2222
periodEnd: number | null;
23+
billingMode: "postpaid" | "prepaid";
2324
}
2425

2526
export interface WhoAmIOrg {

packages/hub/src/types/api/api-collection.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ interface ApiCollectionItemSpace extends ApiCollectionItemBase {
195195
likes: number;
196196
pinned: boolean;
197197
private: boolean;
198+
featured: boolean;
198199
repoType: "space";
199200
title: string;
200201
sdk?: "gradio" | "docker" | "static" | "streamlit";

packages/hub/src/types/api/api-who-am-i.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ interface ApiWhoAmIUser extends ApiWhoAmIEntityBase {
2828
emailVerified: boolean;
2929
isPro: boolean;
3030
orgs: ApiWhoAmIOrg[];
31+
billingMode: "postpaid" | "prepaid";
3132
}
3233

3334
interface ApiWhoAmIApp extends ApiWhoAmIBase {

packages/hub/src/utils/createXorbs.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ export async function* createXorbs(
214214

215215
let cacheData = chunkCache.getChunk(chunk.hash, chunkModule.compute_hmac);
216216
if (cacheData === undefined && chunk.dedup && bytesSinceRemoteDedup >= INTERVAL_BETWEEN_REMOTE_DEDUP) {
217-
const token = await xetWriteToken({ ...params, isPullRequest: params.isPullRequest });
217+
const token = await xetWriteToken(params);
218218
bytesSinceRemoteDedup = 0;
219219

220220
const shardResp = await (params.fetch ?? fetch)(token.casUrl + "/v1/chunks/default/" + chunk.hash, {
@@ -701,7 +701,7 @@ async function loadDedupInfoToCache(
701701

702702
// Try remote dedup lookup if conditions are met
703703
if (chunk.dedup && bytesSinceRemoteDedup >= INTERVAL_BETWEEN_REMOTE_DEDUP) {
704-
const token = await xetWriteToken({ ...params, isPullRequest: params.isPullRequest });
704+
const token = await xetWriteToken(params);
705705
bytesSinceRemoteDedup = 0;
706706

707707
const shardResp = await (params.fetch ?? fetch)(token.casUrl + "/v1/chunks/default/" + chunk.hash, {

packages/hub/src/utils/uploadShards.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,18 @@ export const SHARD_MAGIC_TAG = new Uint8Array([
5151
169,
5252
]);
5353

54+
export interface XetTokenParams {
55+
sessionId?: string;
56+
casUrl?: string;
57+
accessToken?: string;
58+
expiresAt?: Date;
59+
refreshWriteTokenUrl: string;
60+
}
61+
5462
interface UploadShardsParams {
5563
accessToken: string | undefined;
5664
hubUrl: string;
57-
xetRefreshWriteTokenUrl: string;
58-
xetSessionId: string | undefined;
65+
xetParams: XetTokenParams;
5966
fetch?: typeof fetch;
6067
repo: RepoId;
6168
rev: string;
@@ -360,14 +367,14 @@ async function uploadXorb(
360367
xorb: { hash: string; xorb: Uint8Array; files: Array<{ path: string; progress: number; lastSentProgress: number }> },
361368
params: UploadShardsParams
362369
) {
363-
const token = await xetWriteToken({ ...params, isPullRequest: params.isPullRequest });
370+
const token = await xetWriteToken(params);
364371

365372
const resp = await (params.fetch ?? fetch)(`${token.casUrl}/v1/xorbs/default/${xorb.hash}`, {
366373
method: "POST",
367374
body: xorb.xorb,
368375
headers: {
369376
Authorization: `Bearer ${token.accessToken}`,
370-
...(params.xetSessionId ? { "X-Xet-Session-Id": params.xetSessionId } : {}),
377+
...(params.xetParams.sessionId ? { "X-Xet-Session-Id": params.xetParams.sessionId } : {}),
371378
},
372379
...{
373380
progressHint: {
@@ -390,14 +397,14 @@ async function uploadXorb(
390397
}
391398

392399
async function uploadShard(shard: Uint8Array, params: UploadShardsParams) {
393-
const token = await xetWriteToken({ ...params, isPullRequest: params.isPullRequest });
400+
const token = await xetWriteToken(params);
394401

395402
const resp = await (params.fetch ?? fetch)(`${token.casUrl}/v1/shards`, {
396403
method: "POST",
397404
body: shard,
398405
headers: {
399406
Authorization: `Bearer ${token.accessToken}`,
400-
...(params.xetSessionId ? { "X-Xet-Session-Id": params.xetSessionId } : {}),
407+
...(params.xetParams.sessionId ? { "X-Xet-Session-Id": params.xetParams.sessionId } : {}),
401408
},
402409
});
403410

0 commit comments

Comments
 (0)