I am new to python and FastAPI and writing some test code for FastAPI endpoints. I have the following function for unit testing, but when I run it I get back status code 422. Not sure what I am doing wrong:
def test_create_event(self):
my_date = datetime.date(2023, 6, 15)
data = {'id': '1', 'title': 'Winter Cooking', 'host': 'Steven',
'ingredients': ['Apples','Pumpkin','Pecans','Oats'],
'date': my_date.strftime('%m-%d-%Y'), 'participants': ['Steven','Kyle']}
response = requests.post(self.url + '/events/', json=data)
print("response=" + str(response.status_code))
self.assertEqual(response.status_code, 201)
The Event class is defined the following way:
class Event(BaseModel):
id: int
title: str
host: str
ingredients: List[str] = []
date: datetime
participants: List[str] = []
My POST method that works is defined here:
# For event creation via POST
@events_router.post("/events/", status_code=201, response_model=Event)
def create_event(*, event_in: EventCreate) -> Event:
"""
Create a new event (in memory only)
"""
#change below to be based on global variable counter
global counter
new_entry_id = counter
# TODO: change date to server-side data value
event_entry = Event(
id=new_entry_id,
title=event_in.title,
host=event_in.host,
ingredients=event_in.ingredients,
date=event_in.date,
participants=event_in.participants
)
EVENTS.append(event_entry.dict())
counter += 1
return event_entry
Thanks for any advice.
What was the content of the 422 response? The response will say which input failed the validation done by pydantic
.
I haven’t run your code, but my first guess is that it fails to convert the str
value associated to the key date
of the input, into a datetime
value for the attribute date
of Event
. Probably pydantic
just tries to give the string to the constructor of datetime
.
You can provide a custom validation in which you handle how to turn the string into a datetime
value.
Hi Franklin,
I am using PyCharm and the Run screen shows only the error failure when assert does not match:
Traceback (most recent call last):
File "/Users/steve/PycharmProjects/ChefServices/tests/event_tests_old.py", line 36, in test_create_event
self.assertEqual(response.status_code, 201)
AssertionError: 422 != 201
I don’t see which field is the issue within PyCharm, something I was hoping to see.
I will try out using custom validation and see how that goes. I’ll update my results here.
Thanks!
You can print the entire response, instead of only the response.status_code
.
I ran the debugger and found that it’s the date time format:
b’{“detail”:[{“loc”:[“body”,“date”],“msg”:“invalid datetime format”,“type”:“value_error.datetime”}]}’
Looks like you were right about it being datetime related.
I changed the values to ISO8601 format and viola it works.
Here is my new code:
def test_create_event(self):
my_date = my_date = datetime.now(timezone.utc).replace(microsecond=0).astimezone().isoformat()
print("my_date="+my_date)
data = {'id': '1', 'title': 'Winter Cooking', 'host': 'Steven',
'ingredients': ['Apples','Pumpkin','Pecans','Oats'],
'date': my_date, 'participants': ['Steven','Kyle']}
response = requests.post(self.url + '/events/', json=data)
print("response=" + str(response.status_code))
self.assertEqual(response.status_code, 201)
Thanks for getting me on the right path!
1 Like