Search code examples
pythonreactjspython-3.xgoogle-cloud-functionsform-data

How do I access the data in Google Cloud Function written in Python passed via JS FormData from frontend?


I have a ReactJS Frontend, where I am sending a data along with POST request's body payload in the FormData structure, but I am unable to access the data in my Google Cloud Function written Python using request parameter`. Below is my frontend code:

handleUpload = async (file: any, dataFromChild: any) => {
      const token = await auth?.currentUser?.getIdToken();

      if (!token) {
        enqueueSnackbar(`Session Expired. Login again`, { variant: "error" });
        window.location.href("/login")
      }

      if (file) {
        try {
          const snackbarRef = enqueueSnackbar("Uploading File...", {
            variant: "info",
          });
          const payload = new FormData();
          payload.append("file", file[0]);
          payload.append("name", dataFromChild?.fileName);
          payload.append("description", dataFromChild?.fileDesc);
          payload.append("title", dataFromChild?.selectedType);
          payload.append("price", 0);

          const response = await fetch(
            `[Cloud Function URL]`,
            {
              method: "POST",
              headers: {
                Authorization: `Bearer ${token}`,
                "Content-Type": "multipart/form-data",
              },
              body: payload
            }
          );
          closeSnackbar(snackbarRef);
          if (response.ok) {
            enqueueSnackbar(`File uploaded successfully.`, {
              variant: "success",
            });
            this.setState({ fileUploaded: false });

          } else {
            enqueueSnackbar(`Error uploading file.`, { variant: "error" });
            this.setState({ fileUploaded: false });

          }
        } catch (error) {
          enqueueSnackbar(`Error occurred while uploading the file.`, {
            variant: "error",
          });
          this.setState({ fileUploaded: false });

        }
      }
    };

I tried to access the data using following way in Python:

import functions_framework

@functions_framework.http
def main(request):
    headers = set_cors_headers(request)

    if request.method == "OPTIONS":
        return headers

    get_data(request)


def get_data(request):
    print(request.files['file'])
    print(request.form['name']
    .
    .

But it did not get any data. I even tried to get data this way:

def get_data(request):
    print(request.files.get('file')
    print(request.form.get('name')
    .
    .

But all in vain. Anyone tell me what wrong am I doing?


Solution

  • I don't know the reason, but in my case, I had to remove the line of code from my frontend, where it is setting Content-Type to multipart/form-data before sending the POST request. So my updated frontend code looks like:

    handleUpload = async (file: any, dataFromChild: any) => {
          const token = await auth?.currentUser?.getIdToken();
    
          if (!token) {
            enqueueSnackbar(`Session Expired. Login again`, { variant: "error" });
            window.location.href("/login")
          }
    
          if (file) {
            try {
              const snackbarRef = enqueueSnackbar("Uploading File...", {
                variant: "info",
              });
              const payload = new FormData();
              payload.append("file", file[0]);
              payload.append("name", dataFromChild?.fileName);
              payload.append("description", dataFromChild?.fileDesc);
              payload.append("title", dataFromChild?.selectedType);
              payload.append("price", 0);
    
              const response = await fetch(
                `[Cloud Function URL]`,
                {
                  method: "POST",
                  headers: {
                    Authorization: `Bearer ${token}`,
                    "Content-Type": "multipart/form-data", // REMOVED THIS LINE
                  },
                  body: payload
                }
              );
              closeSnackbar(snackbarRef);
              if (response.ok) {
                enqueueSnackbar(`File uploaded successfully.`, {
                  variant: "success",
                });
                this.setState({ fileUploaded: false });
    
              } else {
                enqueueSnackbar(`Error uploading file.`, { variant: "error" });
                this.setState({ fileUploaded: false });
    
              }
            } catch (error) {
              enqueueSnackbar(`Error occurred while uploading the file.`, {
                variant: "error",
              });
              this.setState({ fileUploaded: false });
    
            }
          }
        };