API Requests for Multiple Forms Returns 400 Error on Python Flask

Issue

I’m building a recipes website that collects data from Spoonacular’s API.

The user can search by Recipe, by Ingredients or by Nutrients.

findByIngredients = "recipes/findByIngredients"
findByRecipe = "recipes/complexSearch"
findByNutrients = "recipes/findByNutrients"
randomFind = "recipes/random"

@app.route('/')
def search_page():
  return render_template('search.html')

@app.route('/recipes')
def get_recipes():
 
  if (str(request.args['recipe']).strip() != ""):
      # If there is a recipe
      querystring = {"query":request.args['recipe']}
      response = requests.request("GET", url + findByRecipe, headers=headers, params=querystring).json()
      return render_template('recipes.html', recipes=response)

  if (str(request.args['ingredients']).strip() != ""):
      # If there is a list of ingredients -> list
      querystring = {"number":"5","ranking":"1","ingredients":request.args['ingredients']}
      response = requests.request("GET", url + findByIngredients, headers=headers, params=querystring).json()
      return render_template('recipes.html', recipes=response)

  if (str(request.args['nutrients']).strip() != ""):
      # If there is a list of nutrients -> list
      querystring = {"number":"5","ranking":"1","minProtein":request.args['nutrients']}      
      response = requests.request("GET", url + findByNutrients, headers=headers, params=querystring).json()
      return render_template('recipes.html', recipes=response)

  else:
        print("No recipes found.")

The search works if I only have one if condition and comment the others. But when I uncomment the others, only the first one will work. The above code returns a 400 Bad Request error on the Ingredients and Nutrients search types.

This is what each form on my search.html page looks like:

<form class="d-flex justify-content-center" action="/recipes">
 <div class="input-group mb-3" style="max-width: 50%;">
   <input type="text" class="form-control" placeholder="Apple pie" aria-label="recipe" aria-describedby="recipe" name="recipe">
   <div class="input-group-append">
    <button class="btn btn-primary" type="submit" id="query">Let's go!</button>
   </div>          
 </div>
</form>

Update

My code currently looks like this, but the second and third conditions still returns 400 error codes when the search forms are submitted.

@app.route('/recipes')
def get_recipes():
 
  if (str(request.args['recipe']).strip() != ""):
    querystring = {"query":request.args['recipe']}
    response = requests.request("GET", url + findByRecipe, headers=headers, params=querystring).json()

  elif (str(request.args['ingredients']).strip() != ""):
    querystring = {"number":"5","ranking":"1","ingredients":request.args['ingredients']}
    response = requests.request("GET", url + findByIngredients, headers=headers, params=querystring).json()
      
  elif (str(request.args['nutrients']).strip() != ""):
    querystring = {"number":"5","ranking":"1","minProtein":request.args['nutrients']}      
    response = requests.request("GET", url + findByNutrients, headers=headers, params=querystring).json()
      
  else:
    print("No recipes found.")
  
  return render_template('recipes.html', recipes=response)

Solution

So it must not be the most pythonic way of doing this, but I managed to make my code work by defining different routes for each form:

@app.route('/recipes')
def get_recipes():

  if (str(request.args['recipe']).strip() != ""):
    querystring = {"query":request.args['recipe']}
    response = requests.request("GET", url + findByRecipe, headers=headers, params=querystring).json()
    return render_template('recipes.html', recipes=response)

  else:
    print("No recipes found.")

@app.route('/ingredients')
def get_ingredients():

  if (str(request.args['ingredients']).strip() != ""):
    querystring = {"number":"5","ranking":"1","ingredients":request.args['ingredients']}
    response = requests.request("GET", url + findByIngredients, headers=headers, params=querystring).json()
    return render_template('recipes.html', recipes=response)
      
  else:
    print("No recipes found.")

@app.route('/nutrients')
def get_nutrients():
      
  if (str(request.args['nutrients']).strip() != ""):
    querystring = {"number":"5","ranking":"1","minProtein":request.args['nutrients']}      
    response = requests.request("GET", url + findByNutrients, headers=headers, params=querystring).json()
    return render_template('recipes.html', recipes=response)
      
  else:
    print("No recipes found.")

Answered By – mdeotti

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published