"FastAPI POST Request Returning 400 Bad Request with Optional Parameters, openai app"

814 views Asked by At

I am developing an API using FastAPI and have encountered an issue with a POST endpoint that accepts optional text or file parameters. Despite setting default values for these parameters, I keep receiving a 400 Bad Request error.

Here's the relevant part of my code:

from dotenv import load_dotenv
load_dotenv()

from fastapi import APIRouter, HTTPException, UploadFile, File
import base64
import os
from ai_interaction.prompt import assemble_prompt
from ai_interaction.llm import stream_openai_response

router = APIRouter()

@router.post("/query")  
async def process_user_query(text: str = None, file: UploadFile = File(None)):
    print("Received text:", text)
    print("Received file:", file)
    api_key = os.getenv("OPENAI_API_KEY")
    if not api_key:
        raise HTTPException(status_code=500, detail="API key not configured.")

    if not text and not file:
        raise HTTPException(status_code=400, detail="No text or file provided.")

    if text:
        image_url = text  # Add URL validation here
    elif file:
        image_url = await process_uploaded_file(file)

    prompt = assemble_prompt(image_url)
    response = await stream_openai_response(prompt, api_key)
    return {"response": response}

async def process_uploaded_file(file: UploadFile):
    content = await file.read()
    base64_encoded = base64.b64encode(content).decode('utf-8')
    file_url = f"data:{file.content_type};base64,{base64_encoded}"
    await file.close()
    return file_url 
import requests

url = "http://localhost:8000/api/query"
payload = [{"text": "Explain the water molecule structure"}]
response = requests.post(url, json=payload)
print("Status Code:", response.status_code)
print("Response Body:", response.json())
1

There are 1 answers

1
KRSpinelli On BEST ANSWER

Try parsing the request body using BaseModel. The code is receiving the json input and doesn't inherently know how to split that into two variables. Something like this worked when I ran your code on my machine.

from pydantic import BaseModel


class Item(BaseModel):
    text: str = None
    file: UploadFile = File(None)
    
router = APIRouter()

@router.post("/query") 
async def process_user_query(item: Item):
    text = item.text
    file = item.file