Home > Software engineering >  FastAPI POST Pydantic method unit testing redirecting status_code 307 instead of 200
FastAPI POST Pydantic method unit testing redirecting status_code 307 instead of 200

Time:10-01

I have a test case where I am testing a POST service using pytest hosted with FastAPI Uvicorn. However the response is getting responded with status code 307. But this doesn't happen on actual webservice is tested through a browser or curl. What is happening here?

from fastapi.testclient import TestClient
from src.main import app
import json

client = TestClient(app)

def test_get_confidence_ws():
    data = {
        "acc_id": 1234567801,
        "remoteIp": "127.255.255.255",
        "userAgent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:104.0) Gecko/20100101 Firefox/104.0"
    }
    response = client.post("/confidence", json=json.dumps(data))
    assert response.status_code == 200

Test response

>       assert response.status_code == 200
E       assert 307 == 200
E           where 307 = <Response [307]>.status_code

EDIT:

Actual endpoint that is tested:

@app.post("/confidence/")
def get_confidence(json: LoginClassifierSchema):
    ...
    response = {
           "key" : "value"
        }
    return response

CodePudding user response:

Thanks @MatsLindh and @Vaizki for your responses. The problem was indeed with / and Validation. I will explain in detail so as this benefits the community.

1>If you are getting redirected to 307 this is indeed you have an extra '/' in the endpoint.

2>If you are getting 422 it is most likely a parsing issue. In my case I was using pydantic and though pydantic models are dictionary like, they are not dictionaries. Therefore to get the exact keys you need to convert the data at endpoint to a dictionary by calling data.dict(). eg.,

@app.post("/confidence")
def get_confidence(data: LoginClassifierSchema):
     data = data.dict()
     ...
     ...
     return JSONResponse({"key":"val"}, status_code=200)

In order to understand at an early stage it is a validation issue, add a exception handler method to your app class with endpoints.

from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
from fastapi.exceptions import RequestValidationError

@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request: Request, exc: RequestValidationError):
        """
        This catches the schema validation error made during the call
        """
        validation_err = {"exception": "RequestValidationError: unable to parse input, "   str(exc)}
        return JSONResponse(validation_err, status_code=400)
  • Related