rainbow12
rainbow12

Reputation: 477

How to send optional parameters using HTML checkboxes when uploading file to FastAPI?

I would like to upload a file that is going to be analyzed with a package that can have multiple parameters. For instance, I would like to upload the audio file, and then check some optional parameters to analyze this audio. Here is an example of how the frontend should look like:

enter image description here

However, I don't quite understand how to implement this in the API. Can anyone please help me out?

Here is the code I have so far:

class audiofILE(BaseModel):
    name : str
    speech : str
    music: str
    noise: str


app = FastAPI()

templates = Jinja2Templates(directory="template")

@app.get('/home/{user_name}', response_class=HTMLResponse)
def write_home(request: Request, user_name: str):
    return templates.TemplateResponse("basic_form.html", {"request": request, "username": user_name})

@app.post("/submitform")
async def handle_form(assignment: str = Form(...), audioFile: UploadFile = File(...)):
    try:
        seg = Segmenter()
        segmentation = seg(audioFile.filename)
        segmentation_1 = pd.DataFrame.from_records(segmentation, columns=['labels', 'start', 'stop'])
        if noise :
            result =
            return HTMLResponse(content=segmentation_1.to_html(), status_code=200)

    except Exception as e:
        return HTMLResponse(content={'message': str(e)}, status_code=400)

HTML code:

<!DOCTYPE html>
<html>
    <head>
        <title>Awesome Form</title>
        <link href="{{ url_for('static', path='/styles.css') }}" rel="stylesheet">
    </head>
    <body>
        <h1>Super Realistic Form</h1>
        <form method="POST" enctype="multipart/form-data">
            <input type="file" name="file"><br>
            <input type="checkbox" id="multiply_by_2" name="multiply_by_2" value="True">
            <input type="submit" value="Submit">
        </form>
    </body>
</html>

Any help would be appreciated, thanks.

Upvotes: 2

Views: 913

Answers (1)

Chris
Chris

Reputation: 34551

Please have a look at Method 1 of this answer, which provides an example on how to submit both Form and File data together.

In your example, you have to make sure to include the action attribute (which specifies the URL that processes the form submission) in the HTML <form>, as well as define the name attribute (which specifies the name of the <input> element) using the same key/name you declared for the parameters in your endpoint. You can have the various parameters accompanying the audio file declared as Optional with False as the default value, and have the frontend send True only if they are selected by the user.

Working Example:

app.py

from fastapi import FastAPI, Form, File, UploadFile, Request
from typing import Optional
from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates

app = FastAPI()
templates = Jinja2Templates(directory='templates')

@app.post('/submit')
def submit(
    speech: Optional[bool] = Form(False),
    music: Optional[bool] = Form(False),
    noise: Optional[bool] = Form(False),
    audio: UploadFile = File(...)
):
    if noise:
        print('Noise has been selected')
        
    return {'speech': speech, 'music': music, 'noise': noise, 'file': audio.filename}


@app.get('/', response_class=HTMLResponse)
def main(request: Request):
    return templates.TemplateResponse('index.html', {'request': request})

templates/index.html

<!DOCTYPE html>
<html>
   <head>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1">
   </head>
   <body>
      <form method="post" action="/submit"  enctype="multipart/form-data">
         <input type="checkbox" id="speech" name="speech" value="True">
         <label for="speech">Speech</label><br>
         <input type="checkbox" id="music" name="music" value="True">
         <label for="music">Music</label><br>
         <input type="checkbox" id="noise" name="noise" value="True">
         <label for="noise">Noise</label><br><br>
         <label for="audio">Choose audio file</label>
         <input type="file" id="audio" name="audio" onchange="enableSubmitBtn();"><br><br>
         <input type="submit" id="submitBtn" value="submit" disabled>
      </form>
      <script>
         function enableSubmitBtn() {
            document.getElementById('submitBtn').removeAttribute("disabled");
         }
      </script>
   </body>
</html>

Upvotes: 2

Related Questions