0

I first came across a project in which the backend is written in Python (framework flask), and I wrote the frontend in React. It's time to connect a little functionality between these two parts.

The essence of the project is that the user uploads a file, sees its display (name), can click the convert button and receive a file in a different format. The frontend part is written and the backend part is there, I need to connect these two parts, so that by clicking on the convert button (this is the React part), the Python code will run.

I have been reading and watching the best practices for the second day, but I have not succeeded in anything, I hope you can help me.

So, in order.

Next, the it is passed to the parent DisplaySelectedFile component. DisplaySelectedFile is responsible for displaying a button for selecting a file (SelectFileButton), displaying the file itself, a button for starting the conversion, and a few more elements that are not of interest to us

 export default function DisplaySelectedFile() {
    const [fileName, setFileName] = useState(null);
    const [showCard, setShowCard] = useState(false);

    const handleSelectFile = useCallback(
      (file) => {
        setFileName(file);
        file && setShowCard(true);
      },
      [setFileName, setShowCard]
    );
  
    return (
      <div>
       ...
      </div>
    );
  }
Paul
  • 53
  • 3
  • 21
  • 1
    Does this answer your question? [JavaScript: Upload file](https://stackoverflow.com/questions/5587973/javascript-upload-file) – Jared Smith Aug 22 '22 at 14:08
  • 2
    Call your python route with fetch and the file data. – Jared Smith Aug 22 '22 at 14:09
  • @JaredSmith Thank you for paying attention to my question. Yes, my question and the one you suggested are somewhat similar. But it doesn't talk about Python, and that's where the problem lies for me. How, after clicking on the convert button, transfer the execution of the create_transcript_task () function – Paul Aug 22 '22 at 14:33
  • 1
    "Python... that's where the problem lies for me" I am (at least so far) resisting the temptation to write a snarky response to that. Just, and I **repeat**, use `fetch` to POST to your Python route with the file data. I appreciate your respectful tone but pushing back after soliciting and receiving expert help and asserting you know best instead of asking for clarification comes across as...arrogant. – Jared Smith Aug 22 '22 at 14:46
  • 1
    @JaredSmith In no way did I mean to offend you or appear arrogant. Sorry! Thanks for the advice, I'll try to solve the problem myself – Paul Aug 22 '22 at 14:58
  • Just always remember two things: 1. sometimes the person helping you really is ignorant themselves or really does misunderstand your question, but 2. usually the problem is going to be on your end, and communication needs to be framed that way "I'm afraid I don't understand how X answers my question about Y, can you explain?". Same goes for issues with programming languages, libraries, etc. I do the same thing when I'm the one in your shoes. – Jared Smith Aug 22 '22 at 15:02
  • @JaredSmith I still have to ask you for help. Either the task is too simple and I climbed somewhere far away, or my knowledge is simply not enough, or the reason is something else :). When you have free time, could you describe the solution to the problem with an explanation so that I would properly work out this issue (as there are a lot of similar tasks ahead of me, and if I do not deal with one properly, it will be even more difficult in the future ) – Paul Aug 22 '22 at 21:17
  • Your Flask app has a route `/transcript` that accepts a POST request with a file keyed to the name 'file', so just send it what it expects in a click handler on your convert button `const formData = new FormData(); formData.append('file', file); fetch('/transcript', { method: 'POST', body: formData });` where `file` is the state set from the file input `setFile(fileInput.current.files[0]);`, just like in the linked duplicate. You will have to re-jigger your React state a bit so that it's available to be called from/passed to the convert button, but it's really just that simple. – Jared Smith Aug 22 '22 at 23:43

1 Answers1

0

I think the problem should be how to design the DisplaySelectedFile component.

The first option that you could discuss with your back-end guys about the /convert endpoint. The endpoint /convert should support the callback onUploadProgress which return the upload process.

The second option that you could polling call the /status endpoint to get the upload process. Here is an example code:

export default function DisplaySelectedFile() {
  const [fileName, setFileName] = useState(null);
  const [currentFile, setCurrentFile] = useState(undefined); // store the current upload file
  const [showCard, setShowCard] = useState(false);

  // save the files to the state
  const selectFile = (event) => {
    // I'm assuming that you support upload single file
    const file = event.target.files[0];
    setCurrentFile(file);
    setFileName(file?.name); 
  };
  const getFile = async(task_id) => {
    const interval = setInterval(() => {
      fetch(`http://www.yourEnpoint.com/status?id=${task_id}`, { // Your GET endpoint
        method: 'GET',
        headers: {
          // Content-Type may need to be completely **omitted**
          // or you may need something
          "Content-Type": "You will perhaps need to define a content-type here"
        },
      }).then((context) => {
        if(context?.get_link) {
          clearInterval(interval)
        }
      })
    }, 500)
  }

  const handleConvert = () => {
    fetch('http://www.yourEnpoint.com/transcript', { // Your POST endpoint
    method: 'POST',
    headers: {
      // Content-Type may need to be completely **omitted**
      // or you may need something
      "Content-Type": "You will perhaps need to define a content-type here"
    },
    body: currentFile // This is your file object
    }).then((response) => {
      return getFile(response.task_id);
    })
    .then((context) => {
      console.log(context); // Please do the further steps
    })
    .catch(() => {
      console.log("Could not upload the file!");
      setCurrentFile(undefined);
    });
    setCurrentFile(undefined);
  }

  return (
    <div>
      <SelectFileButton onChange={selectFile} />
      <div>
          {showCard && (
            <TableHead sx={styles.CommonStyle}>
              <TableRow >
                
                  <TableCell sx={styles.CellStyleFileName}>
                    {fileName}
                  </TableCell>
    
                  <TableCell sx={styles.CellStyleButtonAndCross}>
                    <ConvertFileButton onClick={handleConvert}></ConvertFileButton>
                  </TableCell>

              </TableRow>
            </TableHead>
          )}
      </div>
    </div>
  );
}
Vu Luu
  • 792
  • 5
  • 16