pythonfastapiopenai-apihttp-status-code-400

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


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())

Solution

  • 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