Refactor file upload to use SDK instead of XMLHttpRequest
Some checks failed
Build and Push Docker Images / changes (push) Successful in 4s
Build and Push Docker Images / build-backend (push) Successful in 50s
Build and Push Docker Images / build-frontend (push) Failing after 47s

Replaced manual XMLHttpRequest implementation with the SDK's `uploadFile` method for handling file uploads to presigned URLs. This simplifies the code, leverages built-in features like progress tracking, and improves error handling. Added token extraction and upload progress updates to maintain functionality.
This commit is contained in:
2025-03-14 00:05:26 +01:00
parent 0cf5498762
commit b47dbaeb0b
2 changed files with 45 additions and 18 deletions

View File

@@ -17,7 +17,8 @@ logger.info(f"Starting app!!!")
app = FastAPI( app = FastAPI(
title=settings.PROJECT_NAME, title=settings.PROJECT_NAME,
version=settings.VERSION, version=settings.VERSION,
openapi_url=f"{settings.API_VERSION_STR}/openapi.json" openapi_url=f"{settings.API_VERSION_STR}/openapi.json",
debug=True,
) )
# Set up CORS middleware # Set up CORS middleware

View File

@@ -1,6 +1,10 @@
import { useState, useCallback, useEffect } from "react"; import { useState, useCallback, useEffect } from "react";
import { useMutation } from "@tanstack/react-query"; import { useMutation } from "@tanstack/react-query";
import { generatePresignedUrl, PresignedUrlResponse } from "@/client"; import {
generatePresignedUrl,
uploadFile as uploadFileSdk,
PresignedUrlResponse,
} from "@/client";
export interface FileUploadState { export interface FileUploadState {
file?: File; file?: File;
@@ -58,26 +62,48 @@ export function usePresignedUpload(options: UsePresignedUploadOptions = {}) {
const uploadFileToPresignedUrl = useCallback( const uploadFileToPresignedUrl = useCallback(
async (file: File, uploadUrl: string): Promise<void> => { async (file: File, uploadUrl: string): Promise<void> => {
return new Promise<void>((resolve, reject) => { return new Promise<void>((resolve, reject) => {
const xhr = new XMLHttpRequest(); try {
// Use the SDK's uploadFile method instead of direct XMLHttpRequest
xhr.upload.onprogress = ({ loaded, total }) => { // Create form data for the file
const progress = total ? Math.round((loaded / total) * 100) : 0; const formData = new FormData();
setUploadState((prev) => ({ ...prev, progress })); formData.append("file", file);
};
xhr.onload = () => { // Get the token from the upload URL
if (xhr.status >= 200 && xhr.status < 300) { // Assuming the uploadUrl format has a token part after the last '/'
resolve(); const token = uploadUrl.split("/").pop();
} else {
reject(new Error(`Upload failed: ${xhr.status} ${xhr.statusText}`)); if (!token) {
reject(new Error("Invalid upload URL - missing token"));
return;
} }
};
xhr.onerror = () => // Create a progress tracker
reject(new Error("Network error during file upload.")); const onProgress = (progressEvent: any) => {
xhr.open("PUT", uploadUrl); const progress =
xhr.setRequestHeader("Content-Type", file.type); progressEvent.loaded && progressEvent.total
xhr.send(file); ? Math.round((progressEvent.loaded / progressEvent.total) * 100)
: 0;
setUploadState((prev) => ({ ...prev, progress }));
};
// Call the SDK's upload method
uploadFileSdk({
path: { token },
body: { file },
onUploadProgress: onProgress,
})
.then(() => {
resolve();
})
.catch((error: any) => {
reject(
new Error(`Upload failed: ${error.message || "Unknown error"}`),
);
});
} catch (error) {
reject(new Error(`Network error during file upload: ${error}`));
}
}); });
}, },
[], [],