Parsing REST API Payload and Query Parameters With Flask.

Ahmed Nafies
Jun 17 · 3 min read

The easiest way for parsing request payload and query parameters

Image for post
Image for post

Intro

Marshmallow

here is an example of marshmallow

from datetime import date
from pprint import pprint

from marshmallow import Schema, fields


class ArtistSchema(Schema):
name = fields.Str()


class AlbumSchema(Schema):
title = fields.Str()
release_date = fields.Date()
artist = fields.Nested(ArtistSchema())


bowie = dict(name="David Bowie")
album = dict(artist=bowie, title="Hunky Dory", release_date=date(1971, 12, 17))

schema = AlbumSchema()
result = schema.dump(album)
pprint(result, indent=2)
# { 'artist': {'name': 'David Bowie'},
# 'release_date': '1971-12-17',
# 'title': 'Hunky Dory'

The Pros

The Cons

  1. It is old and not using python annotations.
  2. Documentation is terrible and ugly

Pydantic

The Pros

  1. Documentation is fabulous, check here
  2. No dump or load
  3. Can be used for settings management as well

The Cons

  1. There are not much flask extensions/packages built on top of it

The same example written using pydantic

from datetime import date
from pprint import pprint

from pydantic import BaseModel


class ArtistSchema(BaseModel):
name: str


class AlbumSchema(BaseModel):
title: str
release_date: date
artist: ArtistSchema
bowie = dict(name="David Bowie")
album = dict(artist=bowie, title="Hunky Dory", release_date=date(1971, 12, 17))

schema = AlbumSchema(**album)

pprint(result.dict(), indent=2)
# { 'artist': {'name': 'David Bowie'},
# 'release_date': '1971-12-17',
# 'title': 'Hunky Dory'

Here is the same exact example written in a much more intuitive way.

Webargs

from flask import Flask
from webargs import fields
from webargs.flaskparser import use_args
from marshmallow import Schema, fields
app = Flask(__name__)class user(BaseModel):
name = fields.Str()

@app.route("/")
@use_args(user(), location="query")
def index(args):
return "Hello " + args["name"]


if __name__ == "__main__":
app.run()

Luckily there is another webargs package which is using pydantic now, called pydantic-webargs

from flask import Flask
from pydantic import BaseModel
from pydantic_webargs import webargs
app = Flask(__name__)class User(BaseModel):
name: str
@app.route("/")
@webargs(query=User)
def index(**kwargs):
return "Hello " + kwargs["name"]


if __name__ == "__main__":
app.run()

Conclusion

The Startup

Medium's largest active publication, followed by +730K people. Follow to join our community.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store