Friday, 26 August 2022

Connect React to Flask project

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.

The SelectFileButton component is responsible for building a button for selecting a file

  export default function SelectFileButton(props) {
    const {setFileName} = props;
    const [file, setFile] = useState(null);

    const fileInput = useRef();
    const selectFile = () => {
        fileInput.current.click();
    };

    const updateName = () => {
        setFile(fileInput.current.files[0]);
        setFileName(fileInput.current.files[0]?.name);
    }
    
    return (
        <div>
            <input  type="file" 
                    style= 
                    ref={fileInput} 
                    onChange={(event)=> { updateName(event)  }} 
                    onClick={(event)=> { event.target.value = null}}/>
            
            <Button variant="contained" 
                    color="primary"  
                    onClick={selectFile} 
                    sx={styles.DispositionBottom} 
                    style=>
             <span>Upload</span>
            </Button> 
        </div>
    );
}

Next, the SelectFileButton 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>
        <SelectFileButton setFileName={handleSelectFile} />
        
        <div>
            {showCard && (
              <TableHead sx={styles.CommonStyle}>
                <TableRow >
                  
                    <TableCell sx={styles.CellStyleFileName}>
                      {fileName}
                    </TableCell>
      
                    <TableCell sx={styles.CellStyleButtonAndCross}>
                      <ConvertFileButton></ConvertFileButton>
                    </TableCell>

                </TableRow>
              </TableHead>
            )}
        </div>
      </div>
    );
  }

And the button itself, which should be responsible for converting the file

 export default function ConvertFileButton () {
    return (
        <Button>CONVERT</Button>
    )
}

Next, the most difficult question for me is to connect this button to a function (written in Python using a flask) that converts the file

    @mod.route('/transcript', methods=['POST'])
def create_transcript_task():
    if request.method == 'POST':
        if 'file' not in request.files:
            return "Something went wrong !"

        user_file = request.files['file']
        if user_file.filename == '':
            return "file name not found ..."

        else:
            path = os.path.join(os.getcwd(), 'static', user_file.filename)
            user_file.save(path)

            save_path = os.path.join(os.getcwd(), 'static')

            job = queue.enqueue(run_pipeline, path, save_path, job_timeout=-1, result_ttl=-1)
            job.meta['file_name'] = user_file.filename
            task_id = job.get_id()

        print('Run job ', get_job_from_id(queue, task_id))
        return redirect(url_for('backend.status_page') + f'?id={task_id}')

Function that reflects the download status

    @mod.route('/status', methods=['GET'])
def status_page():
    try:
        task_id = request.args.get('id', None)
        rq_job = rq.job.Job.fetch(task_id, connection=queue.connection)
        progress = rq_job.meta.get('progress', None)
        context = {}
        if progress is None:
            context['not_started'] = True
        elif progress < 100:
            context['progress'] = int(progress)
        else:
            context['get_link'] = url_for('backend.get_result') + f'?id={task_id}'

        return render_template('status.html', **context)
    except Exception as e:
        return render_template('error_page.html', error=str(e))

Yes, the question turned out to be very big. If I explained something wrong, then ask me questions. I hope you help me



from Connect React to Flask project

No comments:

Post a Comment