Upload .csv with FastAPI and JS fetch

Viewed 3186

My app uses React on the frontend and FastAPI on the backend.

I'm trying to upload a csv file to my server.

On submitting a form, this gets called:

  const onSubmit = async (e) => {
    e.preventDefault();
    const formData = new FormData();
    formData.append("file", file);
    fetch("/api/textitems/upload", {
      method: "POST",
      body: formData,
    });
  };

The data is received by:

@app.post('/api/textitems/upload')
def upload_file(csv_file: UploadFile = File(...)):
    dataframe = pd.read_csv(csv_file.file)
    return dataframe.head()

I keep getting INFO: 127.0.0.1:0 - "POST /api/textitems/upload HTTP/1.1" 422 Unprocessable Entity errors.

I am able to successfully perform the post request with curl like so:

curl -X POST "http://localhost:8000/api/textitems/upload" -H "accept: application/json" -H "Content-Type: multipart/form-data" -F "csv_file=@exp_prod.csv;type=text/csv"

Any advice about where I'm going wrong when using Javascript though?

3 Answers

I did eventually solve this. Isabi's answer helped me, as did learning about FormData's append method. Here are the working code snippets in case anyone finds them useful.

  const onSubmit = async (e) => {
    e.preventDefault();
    const formData = new FormData();
    formData.append("file", file, file.name);
    await fetch(`/api/textitems/upload`, {
      method: "POST",
      body: formData,
    })
@app.post('/api/textitems/upload')
def upload_file(file: UploadFile = File(...), db: Session = Depends(get_db)):
    df = pd.read_csv(file.file).head()
    return df

Set Content-Type header to multipart/form-data on your request:

  const onSubmit = async (e) => {
    e.preventDefault();
    const formData = new FormData();
    formData.append("file", file);
    fetch("/api/textitems/upload", {
      method: "POST",
      body: formData,
      headers: {
          'Content-Type': 'multipart/form-data',
      }
    });
  };
Related