From b71a6515f068c2a122e2049c8ebaab3e82d4bce9 Mon Sep 17 00:00:00 2001 From: Roman Donchenko Date: Thu, 16 Mar 2023 13:26:16 +0300 Subject: [PATCH 1/9] server-proxy.ts: remove redundant JSON stringification Axios will automatically encode the request body as JSON and add the appropriate `Content-Type` if given an object. --- cvat-core/src/server-proxy.ts | 142 ++++++---------------------------- 1 file changed, 25 insertions(+), 117 deletions(-) diff --git a/cvat-core/src/server-proxy.ts b/cvat-core/src/server-proxy.ts index cd3840841942..f6c8f3cc61c4 100644 --- a/cvat-core/src/server-proxy.ts +++ b/cvat-core/src/server-proxy.ts @@ -365,7 +365,7 @@ async function register( ): Promise { let response = null; try { - const data = JSON.stringify({ + response = await Axios.post(`${config.backendAPI}/auth/register`, { username, first_name: firstName, last_name: lastName, @@ -374,11 +374,6 @@ async function register( password2: password, confirmations, }); - response = await Axios.post(`${config.backendAPI}/auth/register`, data, { - headers: { - 'Content-Type': 'application/json', - }, - }); setAuthData(response); } catch (errorData) { throw generateError(errorData); @@ -413,16 +408,11 @@ async function logout(): Promise { async function changePassword(oldPassword: string, newPassword1: string, newPassword2: string): Promise { try { - const data = JSON.stringify({ + await Axios.post(`${config.backendAPI}/auth/password/change`, { old_password: oldPassword, new_password1: newPassword1, new_password2: newPassword2, }); - await Axios.post(`${config.backendAPI}/auth/password/change`, data, { - headers: { - 'Content-Type': 'application/json', - }, - }); } catch (errorData) { throw generateError(errorData); } @@ -430,14 +420,9 @@ async function changePassword(oldPassword: string, newPassword1: string, newPass async function requestPasswordReset(email: string): Promise { try { - const data = JSON.stringify({ + await Axios.post(`${config.backendAPI}/auth/password/reset`, { email, }); - await Axios.post(`${config.backendAPI}/auth/password/reset`, data, { - headers: { - 'Content-Type': 'application/json', - }, - }); } catch (errorData) { throw generateError(errorData); } @@ -445,17 +430,12 @@ async function requestPasswordReset(email: string): Promise { async function resetPassword(newPassword1: string, newPassword2: string, uid: string, _token: string): Promise { try { - const data = JSON.stringify({ + await Axios.post(`${config.backendAPI}/auth/password/reset/confirm`, { new_password1: newPassword1, new_password2: newPassword2, uid, token: _token, }); - await Axios.post(`${config.backendAPI}/auth/password/reset/confirm`, data, { - headers: { - 'Content-Type': 'application/json', - }, - }); } catch (errorData) { throw generateError(errorData); } @@ -628,11 +608,7 @@ async function saveProject(id: number, projectData: Partial): let response = null; try { - response = await Axios.patch(`${backendAPI}/projects/${id}`, JSON.stringify(projectData), { - headers: { - 'Content-Type': 'application/json', - }, - }); + response = await Axios.patch(`${backendAPI}/projects/${id}`, projectData); } catch (errorData) { throw generateError(errorData); } @@ -654,11 +630,7 @@ async function createProject(projectSpec: SerializedProject): Promise): Promise< let response = null; try { - response = await Axios.patch(`${backendAPI}/tasks/${id}`, JSON.stringify(taskData), { - headers: { - 'Content-Type': 'application/json', - }, - }); + response = await Axios.patch(`${backendAPI}/tasks/${id}`, taskData); } catch (errorData) { throw generateError(errorData); } @@ -1172,11 +1140,8 @@ async function createTask(taskSpec, taskDataSpec, onUpdate) { onUpdate('The task is being created on the server..', null); try { - response = await Axios.post(`${backendAPI}/tasks`, JSON.stringify(taskSpec), { + response = await Axios.post(`${backendAPI}/tasks`, taskSpec, { params, - headers: { - 'Content-Type': 'application/json', - }, }); } catch (errorData) { throw generateError(errorData); @@ -1342,11 +1307,7 @@ async function createComment(data) { let response = null; try { - response = await Axios.post(`${backendAPI}/comments`, JSON.stringify(data), { - headers: { - 'Content-Type': 'application/json', - }, - }); + response = await Axios.post(`${backendAPI}/comments`, data); } catch (errorData) { throw generateError(errorData); } @@ -1360,11 +1321,8 @@ async function createIssue(data) { let response = null; try { const organization = enableOrganization(); - response = await Axios.post(`${backendAPI}/issues`, JSON.stringify(data), { + response = await Axios.post(`${backendAPI}/issues`, data, { params: { ...organization }, - headers: { - 'Content-Type': 'application/json', - }, }); const commentsResponse = await fetchAll(`${backendAPI}/comments`, { @@ -1385,11 +1343,7 @@ async function updateIssue(issueID, data) { let response = null; try { - response = await Axios.patch(`${backendAPI}/issues/${issueID}`, JSON.stringify(data), { - headers: { - 'Content-Type': 'application/json', - }, - }); + response = await Axios.patch(`${backendAPI}/issues/${issueID}`, data); } catch (errorData) { throw generateError(errorData); } @@ -1412,11 +1366,7 @@ async function saveJob(id: number, jobData: Partial): Promise { const { backendAPI } = config; try { - const response = await Axios.post(`${backendAPI}/webhooks`, JSON.stringify(webhookData), { + const response = await Axios.post(`${backendAPI}/webhooks`, webhookData, { params, - headers: { - 'Content-Type': 'application/json', - }, }); return response.data; } catch (errorData) { @@ -2243,13 +2155,9 @@ async function updateWebhook(webhookID: number, webhookData: any): Promise const { backendAPI } = config; try { - const response = await Axios - .patch(`${backendAPI}/webhooks/${webhookID}`, JSON.stringify(webhookData), { - params, - headers: { - 'Content-Type': 'application/json', - }, - }); + const response = await Axios.patch(`${backendAPI}/webhooks/${webhookID}`, webhookData, { + params, + }); return response.data; } catch (errorData) { throw generateError(errorData); From 7b6ce9f346dca6e4a1d1c17cc69e73cf9fc21eec Mon Sep 17 00:00:00 2001 From: Roman Donchenko Date: Thu, 16 Mar 2023 13:36:39 +0300 Subject: [PATCH 2/9] server-proxy.ts: remove redundant Axios parameters * `Content-Type` when there's no content; * duplicate method names; * empty configs. --- cvat-core/src/server-proxy.ts | 48 ++++++----------------------------- 1 file changed, 8 insertions(+), 40 deletions(-) diff --git a/cvat-core/src/server-proxy.ts b/cvat-core/src/server-proxy.ts index f6c8f3cc61c4..cd199830bee7 100644 --- a/cvat-core/src/server-proxy.ts +++ b/cvat-core/src/server-proxy.ts @@ -683,9 +683,6 @@ async function deleteTask(id: number, organizationID: string | null = null): Pro try { await Axios.delete(`${backendAPI}/tasks/${id}`, { ...(organizationID ? { org: organizationID } : {}), - headers: { - 'Content-Type': 'application/json', - }, }); } catch (errorData) { throw generateError(errorData); @@ -707,7 +704,7 @@ async function getLabels(filter: { async function deleteLabel(id: number): Promise { const { backendAPI } = config; try { - await Axios.delete(`${backendAPI}/labels/${id}`, { method: 'DELETE' }); + await Axios.delete(`${backendAPI}/labels/${id}`); } catch (errorData) { throw generateError(errorData); } @@ -717,7 +714,7 @@ async function updateLabel(id: number, body: SerializedLabel): Promise { let response = null; try { - response = await Axios.get(`${backendAPI}/${session}s/${jid}/data/meta`, { - }); + response = await Axios.get(`${backendAPI}/${session}s/${jid}/data/meta`); } catch (errorData) { throw generateError(errorData); } @@ -1553,8 +1549,7 @@ async function getFunctionProviders() { const { backendAPI } = config; try { - const response = await Axios.get(`${backendAPI}/functions/info`, { - }); + const response = await Axios.get(`${backendAPI}/functions/info`); return response.data; } catch (errorData) { if (errorData.response.status === 404) { @@ -1568,11 +1563,7 @@ async function deleteFunction(functionId: number) { const { backendAPI } = config; try { - await Axios.delete(`${backendAPI}/functions/${functionId}`, { - headers: { - 'Content-Type': 'application/json', - }, - }); + await Axios.delete(`${backendAPI}/functions/${functionId}`); } catch (errorData) { throw generateError(errorData); } @@ -1746,9 +1737,7 @@ async function cancelFunctionRequest(requestId: string): Promise { const { backendAPI } = config; try { - await Axios.delete(`${backendAPI}/functions/requests/${requestId}`, { - method: 'DELETE', - }); + await Axios.delete(`${backendAPI}/functions/requests/${requestId}`); } catch (errorData) { throw generateError(errorData); } @@ -1867,9 +1856,7 @@ async function cancelLambdaRequest(requestId) { const { backendAPI } = config; try { - await Axios.delete(`${backendAPI}/lambda/requests/${requestId}`, { - method: 'DELETE', - }); + await Axios.delete(`${backendAPI}/lambda/requests/${requestId}`); } catch (errorData) { throw generateError(errorData); } @@ -2012,11 +1999,7 @@ async function deleteOrganization(id) { const { backendAPI } = config; try { - await Axios.delete(`${backendAPI}/organizations/${id}`, { - headers: { - 'Content-Type': 'application/json', - }, - }); + await Axios.delete(`${backendAPI}/organizations/${id}`); } catch (errorData) { throw generateError(errorData); } @@ -2103,9 +2086,6 @@ async function getWebhookDelivery(webhookID: number, deliveryID: number): Promis try { const response = await Axios.get(`${backendAPI}/webhooks/${webhookID}/deliveries/${deliveryID}`, { params, - headers: { - 'Content-Type': 'application/json', - }, }); return response.data; } catch (errorData) { @@ -2124,9 +2104,6 @@ async function getWebhooks(filter, pageSize = 10): Promise { ...filter, page_size: pageSize, }, - headers: { - 'Content-Type': 'application/json', - }, }); response.data.results.count = response.data.count; @@ -2171,9 +2148,6 @@ async function deleteWebhook(webhookID: number): Promise { try { await Axios.delete(`${backendAPI}/webhooks/${webhookID}`, { params, - headers: { - 'Content-Type': 'application/json', - }, }); } catch (errorData) { throw generateError(errorData); @@ -2201,9 +2175,6 @@ async function pingWebhook(webhookID: number): Promise { try { const response = await Axios.post(`${backendAPI}/webhooks/${webhookID}/ping`, { params, - headers: { - 'Content-Type': 'application/json', - }, }); const deliveryID = response.data.id; @@ -2222,9 +2193,6 @@ async function receiveWebhookEvents(type: WebhookSourceType): Promise params: { type, }, - headers: { - 'Content-Type': 'application/json', - }, }); return response.data.events; } catch (errorData) { From ed05fa8edb7bb083cc9645f2282ce74106423fdc Mon Sep 17 00:00:00 2001 From: Roman Donchenko Date: Thu, 16 Mar 2023 13:47:09 +0300 Subject: [PATCH 3/9] server-proxy.ts: refactor `updateAnnotations` to enable typechecking The typechecker knows what arguments `Axios` wants, but it doesn't know what arguments `requestFunc` wants. --- cvat-core/src/server-proxy.ts | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/cvat-core/src/server-proxy.ts b/cvat-core/src/server-proxy.ts index cd199830bee7..d4d8e96ba8dd 100644 --- a/cvat-core/src/server-proxy.ts +++ b/cvat-core/src/server-proxy.ts @@ -1574,20 +1574,18 @@ async function updateAnnotations(session, id, data, action) { const { backendAPI } = config; const url = `${backendAPI}/${session}s/${id}/annotations`; const params = {}; - let requestFunc = null; + let method: string; if (action.toUpperCase() === 'PUT') { - requestFunc = Axios.put.bind(Axios); + method = 'PUT'; } else { - requestFunc = Axios.patch.bind(Axios); + method = 'PATCH'; params.action = action; } let response = null; try { - response = await requestFunc(url, data, { - params, - }); + response = await Axios(url, { method, data, params }); } catch (errorData) { throw generateError(errorData); } From 6e9e57c01096847ce60144b33b8729ebb0008bbb Mon Sep 17 00:00:00 2001 From: Roman Donchenko Date: Thu, 16 Mar 2023 13:50:02 +0300 Subject: [PATCH 4/9] server-proxy.ts: remove redundant object spreading --- cvat-core/src/server-proxy.ts | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/cvat-core/src/server-proxy.ts b/cvat-core/src/server-proxy.ts index d4d8e96ba8dd..d619caa659f7 100644 --- a/cvat-core/src/server-proxy.ts +++ b/cvat-core/src/server-proxy.ts @@ -544,10 +544,7 @@ async function healthCheck( async function serverRequest(url: string, data: object): Promise { try { - const res = await Axios({ - url, - ...data, - }); + const res = await Axios(url, data); return res; } catch (errorData) { throw generateError(errorData); @@ -2042,12 +2039,7 @@ async function updateOrganizationMembership(membershipId, data) { const { backendAPI } = config; let response = null; try { - response = await Axios.patch( - `${backendAPI}/memberships/${membershipId}`, - { - ...data, - }, - ); + response = await Axios.patch(`${backendAPI}/memberships/${membershipId}`, data); } catch (errorData) { throw generateError(errorData); } From 1e5cd630d38529d73c296b9cb2cd284155e2064d Mon Sep 17 00:00:00 2001 From: Roman Donchenko Date: Thu, 16 Mar 2023 14:07:46 +0300 Subject: [PATCH 5/9] server-proxy.ts: fix incorrect parameter passing in `deleteTask` --- cvat-core/src/server-proxy.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cvat-core/src/server-proxy.ts b/cvat-core/src/server-proxy.ts index d619caa659f7..2e4dc32bd290 100644 --- a/cvat-core/src/server-proxy.ts +++ b/cvat-core/src/server-proxy.ts @@ -679,7 +679,9 @@ async function deleteTask(id: number, organizationID: string | null = null): Pro try { await Axios.delete(`${backendAPI}/tasks/${id}`, { - ...(organizationID ? { org: organizationID } : {}), + params: { + ...(organizationID ? { org: organizationID } : {}), + }, }); } catch (errorData) { throw generateError(errorData); From f88540145f861c223b05dead8eafd126e300df63 Mon Sep 17 00:00:00 2001 From: Roman Donchenko Date: Thu, 16 Mar 2023 14:09:10 +0300 Subject: [PATCH 6/9] server-proxy.ts: remove manual query string building in `getCloudStorageContent` --- cvat-core/src/server-proxy.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/cvat-core/src/server-proxy.ts b/cvat-core/src/server-proxy.ts index 2e4dc32bd290..c24e227854c4 100644 --- a/cvat-core/src/server-proxy.ts +++ b/cvat-core/src/server-proxy.ts @@ -1916,10 +1916,12 @@ async function getCloudStorageContent(id, manifestPath) { let response = null; try { - const url = `${backendAPI}/cloudstorages/${id}/content${ - manifestPath ? `?manifest_path=${manifestPath}` : '' - }`; - response = await Axios.get(url); + const url = `${backendAPI}/cloudstorages/${id}/content`; + response = await Axios.get(url, { + params: { + ...(manifestPath ? { manifest_path: manifestPath } : {}), + }, + }); } catch (errorData) { throw generateError(errorData); } From fc4237ea14899c131bd57e9bb109d1c085f89b7c Mon Sep 17 00:00:00 2001 From: Roman Donchenko Date: Thu, 16 Mar 2023 14:11:16 +0300 Subject: [PATCH 7/9] server-proxy.ts: remove `dumpAnnotations` It has been unused since f18b1cb8. --- cvat-core/src/server-proxy.ts | 33 --------------------------------- 1 file changed, 33 deletions(-) diff --git a/cvat-core/src/server-proxy.ts b/cvat-core/src/server-proxy.ts index c24e227854c4..b8cb092e9544 100644 --- a/cvat-core/src/server-proxy.ts +++ b/cvat-core/src/server-proxy.ts @@ -1698,38 +1698,6 @@ async function getFunctionRequestStatus(requestID) { } } -// Session is 'task' or 'job' -async function dumpAnnotations(id, name, format) { - const { backendAPI } = config; - const baseURL = `${backendAPI}/tasks/${id}/annotations`; - const params = enableOrganization(); - params.format = encodeURIComponent(format); - if (name) { - const filename = name.replace(/\//g, '_'); - params.filename = encodeURIComponent(filename); - } - - return new Promise((resolve, reject) => { - async function request() { - Axios.get(baseURL, { - params, - }) - .then((response) => { - if (response.status === 202) { - setTimeout(request, 3000); - } else { - params.action = 'download'; - resolve(`${baseURL}?${new URLSearchParams(params).toString()}`); - } - }) - .catch((errorData) => { - reject(generateError(errorData)); - }); - } - setTimeout(request); - }); -} - async function cancelFunctionRequest(requestId: string): Promise { const { backendAPI } = config; @@ -2268,7 +2236,6 @@ export default Object.freeze({ annotations: Object.freeze({ updateAnnotations, getAnnotations, - dumpAnnotations, uploadAnnotations, }), From f30e43299a6207f2227de506041202829903a57f Mon Sep 17 00:00:00 2001 From: Roman Donchenko Date: Thu, 16 Mar 2023 18:49:04 +0300 Subject: [PATCH 8/9] Update cvat-core version --- cvat-core/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cvat-core/package.json b/cvat-core/package.json index c2e4f2112093..1d0462df1074 100644 --- a/cvat-core/package.json +++ b/cvat-core/package.json @@ -1,6 +1,6 @@ { "name": "cvat-core", - "version": "9.0.0", + "version": "9.0.1", "description": "Part of Computer Vision Tool which presents an interface for client-side integration", "main": "src/api.ts", "scripts": { From 67d9d0ab10320b514c078f76519076abe464b9d7 Mon Sep 17 00:00:00 2001 From: Roman Donchenko Date: Thu, 16 Mar 2023 18:56:46 +0300 Subject: [PATCH 9/9] Update changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 85ef90dca34b..718d8295607a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - An invalid project/org handling in webhooks () +- Cloud storage content listing when the manifest name contains special characters + () ### Security - TDB