From Flask to Fast

Why I Switched Frameworks Mid-Journey

So I switched frameworks from Flask to FastAPI. I'm not totally sure why. It just kind of happened. So maybe I'm kind of jumping the gun here. Talking about switching Python frameworks mid-development hardly seems like an introductory topic for a tiny little blog like this one.

But let me explain.

Process

Were you ever one of those kids that was thrown into the deep end of the pool while your well-intentioned family member (or "friend") watched in glee as you flailed in desperation trying not to drown?

No?

Good for you. That didn't really happen to me either, but, unfortunately, it is something that I tend to do to myself quite often.

Ordinarily, when I'm looking for how to do something in Python, I'm ten steps ahead of where I probably should be.

I end up flapping my metaphorical legs and arms (mostly frantically searching online for answers).

So that's kind of how this blog started in the first place.

Mostly with this question...

Can I build a template-based web app from scratch, and potentially use it as a launchpad to other projects?

While I was initially drawn to Django with their promise to make it "easier to build better Web apps more quickly and with less code," I felt like it would be similar to swimming with floaties on. I needed to jump in the deep end.

No floaties.

Enter Flask

I looked at many comparisons, and as a result, I was inevitably drawn to Flask.

I would be forced to learn from the ground up.

At the time, I didn't even know what a "microframework" was, or the difference between a blueprint and a view. (Is an app factory a place where baby applications are born?)

But I was excited by some great references/tutorials on how to build baby web apps with Flask.

The true challenge would be how to move beyond the many "Hello World" tutorials out there and into a full-fledged, grown-up, adult web app.

At this point, my click-happy nature sent me down tunnels of "best practice" articles, Jinja template documentation, app design patterns, flask modules, etc...

I also landed in areas outside of Flask and Python, such as databases, hosting platforms, and a plethora of corollaries.

Stay Grounded

If that sounds overwhelming, it is. I told you. Deep end.

But back to the topic at hand. Flask seemed to have exactly what I was looking for. It provides a solid foundation.

It is an application that just works with a few lines of code, but has extensive modularity and documentation—given how popular the framework is, there is no shortage of content.

I mean look at this. This is easy!

from flask import Flask

app = Flask(__name__)

@app.route("/")
def hi_there():
    return <p>"Hello... world..."</p>

Awesome!

But then I took a look at all the extensions for Flask and got a little spooked.

Although my learning process was a little overwhelming, I assure you, I have nothing but positive things to say about my experience.

So Why the Switch?

There's no real simple answer as to why I decided to jump ship to another framework.

If anything, I was perfectly happy with my progress. I had a functioning app. I had Jinja templates built that more or less mimic the current design.

I was even interfacing with a local instance of PostgreSQL, and I even had a working skeleton running on a Digital Ocean account (using the introductory credit to pay for the server/database).

I remember that I was dabbling with Flask-SQLAlchemy, a Flask extension that adds support for SQLAlchemy, an Object Relational Mapper and toolkit to help Python developers interface with SQL.

Wait, what?

Yeah, I had no idea what those things even mean.

I promise that I'll have content on this blog that talks about some of these things in more detail (with code examples), but for now, just bear with me.

As I was saying, at the time I was working with it, SQLAlchemy was undergoing some major changes under the hood.

Many of the tutorials and and examples I was using were geared toward how the extension worked prior to early 2021, a time prior to the changes that were coming.

I was tinkering with how I was using SQLAlchemy in my Flask application and felt like I was in way over my head (mind you, I feel this way a lot).

In addition, I started reading and hearing a lot about FastAPI, as well as this classy little library called pydantic.

I had a combination of curiosity and FOMO when it came to these two libraries. And so I asked myself another question:

How hard could it be to migrate what I've already done with Flask into this other framework I know next to nothing about?

Think Fast

So as it turns out, FastAPI also has a very enticing entry point. With just a few lines of code, you can get an app running!

Ah, the simplicity:

from fastapi import FastAPI

app = FastAPI()

@app.get("/")
async def root():
    return {"message": "Hello... world?"}

See?

Easy peasy.

But then, compared to Flask, there's a slight problem.

Seeing as to how the framework is relatively young, there are not a lot of extensions built specifically for/around it—at least not comparatively to Flask.

In addition, many of the tutorials barely get you to the front door of what it can do. (Though that's not as much the case as more people have been using the framework since I started this project.)

Lastly, the framework primarily focuses on APIs (it's in the name), so it theoretically makes very little sense to refactor a "web app" project into FastAPI.

Yet here I am.

There are a multitude of reasons for this, of which I may detail a bit more in subsequent posts, but I will try to address it briefly.

FastAPI is primarily built on top of pydantic, a library that embraces Python type hints as a way to validate data.

It doesn't really sound all that sexy, but in practice, I think it is an awesome tool.

Secondly, the end goal of this journey was not merely to build a blog from the ground up. The journey is the destination.

Ultimately, I want to learn how to use powerful Python tools in meaningful ways.

While I am currently focusing on web-centric development, I know that learning how to build and use APIs could have a lot of impact in what I do down the road.

And finally, if I'm dealing with data, I'm sure that I will see/use pydantic in some form or another going forward, regardless of what development path I take next.

Conclusion

So, here you are, viewing this web page on an app built with FastAPI.

I didn't even mention my jump from PostgreSQL to MongoDB, but that's for another day.

I know this post is more prose than is probably necessary for a blog supposedly devoted to Python.

I don't know if that will be more the norm than the exception, but I also want to be able to provide helpful lessons learned along the way, which will inevitably include code in some form (for those of you who like to copy/paste).

In the meantime, check out the fantastic documentation for FastAPI.

It is an awesome way to get started and provides you most of what you need, even beyond the basic "Hello World" stage.