Python Friday #223: Better Pydantic Models for FastAPI

The basic models we used for our tasks are good to make sure we get the right types. However, if we accept something like int or string, we could get enormously large inputs that are valid strings or numbers but make no sense at all for our application. Let us explore ways to limit our fields to reasonable lengths.

This post is part of my journey to learn Python. You find the code for this post in my PythonFriday repository on GitHub.

 

Update the existing tests

If we introduce new rules to our models, our existing tests may start to fail. The tests got created before we had those limits in place and while the functionality may stay the same, our tests may create no longer valid models.

We can define the new rules and change the tests to comply with them before we make the changes to the models, or we focus on the tests for the new rules in the models and fix the existing tests later. Both approaches work and are fine. Just make sure that everyone in the team is on the same page and understands what your priorities are.

 

Define the new rules

To be more strict in what tasks we accept with our API, we can define these rules:

  • The name must be between 5 and 100 characters.
  • The priority must be greater than 0 and less than 10.
  • The due_date can be between today and one year in the future.

 

Create the new tests

We can create a new test file test_models.py and add the following tests one by one while we make them pass before we add the next one:

 

Refactor the models

For our Pydantic models we can add Fields and specify our validation rules:

 

Fix the OpenAPI exception

While the code above works outside of FastAPI and in our tests, it provokes an exception as soon as we try to open our OpenAPI specification:

While the exception is nearly useless, the problem comes from the due_date field. The code to create the OpenAPI specification just does not like fields on date values.

To make sure we get notified when such errors occur, we add this test that just fetches data from the OpenAPI endpoint and will pass if there is no exception:

We now need to change a few places at once to get everything back to a working state. The order does not matter much, but we may not be able to change the code while all tests stay green.

To fix the OpenAPI problem, we need to remove the Field from due_date and add a validator:

Our OpenAPI test now will work, but the two tests who check the valid due_date start to fail. We can fix them by replacing the assert to match our new validation error message:

Our tests should now all pass and the docs endpoint should be back online:

The docs endpoint now serves our documentation once more.

 

Next

With our strict models in place, we can prevent malicious attackers from flooding our API with endless titles or priority values in the billions. There is much more to the topic of security that we will address in a later post. Next week we revisit the status codes for our endpoints and try to improve them.

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.