Handling Incoming Data with Marshmallow

Handling Incoming Data with Marshmallow

Welcome back! In the previous lesson, we explored defining schemas and serializing data with Marshmallow. Now, we will take it a step further by handling incoming data from a request and automatically validating it using Marshmallow. This is crucial for ensuring that the data your application receives adheres to expected formats and standards.

By the end of this lesson, you will be able to create a Flask endpoint that handles incoming user data, validates it using Marshmallow schemas, and adds it to a mock database.

Recap of Previous Lesson

Here’s a reminder of the initial setup, including the Flask app instance and our mock database:

from flask import Flask

# Initialize a Flask app instance
app = Flask(__name__)

# Mock database as a list of dictionaries
database = [
    {"id": 1, "username": "cosmo", "email": "cosmo@example.com"},
    {"id": 2, "username": "jake", "email": "jake@example.com"},
    {"id": 3, "username": "emma", "email": "emma@example.com"}
]

Defining Required Schema Fields

To handle incoming data properly, we need to specify what valid data looks like using a Marshmallow schema. Let's focus on making certain fields mandatory, like username and email.

Here's an updated version of our schema that enforces these requirements:

from marshmallow import Schema, fields

# Define a Marshmallow schema for user data
class UserSchema(Schema):
    id = fields.Int()
    username = fields.Str(required=True)
    email = fields.Email(required=True)

# Create an instance of the User schema
user_schema = UserSchema()

In this schema, setting required=True for the username and email fields ensures that both fields must be provided and follow their respective data types (string and email format).

On the other hand, the id field is not marked as required because it will be generated automatically when a new user is added. This setup helps keep our user data accurate and complete.

Validating Incoming Data

Now that we've defined our schema, we need to validate incoming data against this schema!

We'll use Marshmallow's load method to load and validate incoming JSON data. If the data is invalid, Marshmallow will raise a ValidationError. Let's see how this works in the context of a Flask route:

from flask import request, jsonify
from marshmallow import ValidationError

# Define a route to handle user creation
@app.route('/users', methods=['POST'])
def create_user():
    try:
        # Validate the incoming JSON data using the User schema
        user_data = user_schema.load(request.get_json())
    except ValidationError as err:
        # Return validation errors as a JSON response
        return jsonify(error = err.messages), 400
  • request.get_json() retrieves the incoming JSON data from the request body.
  • user_schema.load(request.get_json()) attempts to load and validate this data against the UserSchema.
  • If validation fails, a ValidationError is raised, and we catch it in the except block, returning the error messages as a JSON response with a 400 status code.
Sign up

Join the 1M+ learners on CodeSignal

Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal