'iOS - Failed to upload video file from swift to FastAPI server

I took the code for uploading the video file from this question, however, an error occurs.

This is the code to select a video from an album:

var videoURL: URL?

extension ViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {

        picker.dismiss(animated: true, completion: nil)
        if let pickedVideo = info[UIImagePickerController.InfoKey.mediaURL] as? URL {
            videoURL = pickedVideo
}

This is the code to upload the video to the server.

func uploadImage(imageURL: URL?) {
        
        let URL = "http://127.0.0.1:8000/uploadfiles"
        let header : HTTPHeaders = [
            "Content-Type" : "application/json"]
    
    let timestamp = NSDate().timeIntervalSince1970
    
    AF.upload(multipartFormData: { multipartFormData in
        multipartFormData.append(imageURL!, withName: "video", fileName: "\(timestamp).mp4", mimeType: "\(timestamp).mp4")
        
    }, to: URL, usingThreshold: UInt64.init(), method: .post, headers: header).response { response in
        guard let statusCode = response.response?.statusCode,
              statusCode == 200
        else { return }
@IBAction func ButtonClicked(_ sender: UIButton) {
        do {
            uploadImage(imageURL: videoURL!)
 
        } catch {
        }
    }

This is the FastAPI server code:

from fastapi import FastAPI, File, UploadFile
from typing import List
import os

app = FastAPI()

@app.get("/")
def read_root():
  return { "Hello": "World" }

@app.post("/files/")
async def create_files(files: List[bytes] = File(...)):
    return {"file_sizes": [len(file) for file in files]}

@app.post("/uploadfiles")
async def create_upload_files(files: List[UploadFile] = File(...)):
    print('here')
    UPLOAD_DIRECTORY = "./"
    for file in files:
        contents = await file.read()
        with open(os.path.join(UPLOAD_DIRECTORY, file.filename), "wb") as fp:
            fp.write(contents)
        print(file.filename)
    return {"filenames": [file.filename for file in files]}

This is the error:

INFO:     127.0.0.1:65191 - "POST /uploadfiles HTTP/1.1" 422 Unprocessable Entity


Solution 1:[1]

You are attempting to send multipart/form-data (see FastAPI documentation for uploading Files), but you have set the Content-Type header to application/json. Thus, you should remove/change that.

Additionally, on client side you should use the same form key given on server side for the uploaded file, i.e., files (since you defined it as files: List[bytes] = File(...)), not video. This answer demonstrates how to upload a single or multiple files to a FastAPI server. Please have a look at it.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1