Perfect 👍 — let’s do a side-by-side mini example comparing Flask vs FastAPI for the same RESTful API.
This will make it crystal clear how both frameworks work.


🎯 Goal: Build a simple API with two endpoints

  • GET / → returns a welcome message
  • GET /items/{item_id} → returns item details

🐍 1️⃣ Flask Example

# flask_app.py
from flask import Flask, jsonify, request

app = Flask(__name__)

@app.route('/', methods=['GET'])
def home():
    return jsonify({"message": "Welcome to my Flask API!"})

@app.route('/items/<int:item_id>', methods=['GET'])
def get_item(item_id):
    query = request.args.get('q')
    return jsonify({"item_id": item_id, "query": query})

if __name__ == '__main__':
    app.run(debug=True)

▶️ Run it:

python flask_app.py

Visit:

  • http://127.0.0.1:5000/
  • http://127.0.0.1:5000/items/10?q=test

2️⃣ FastAPI Example

# fastapi_app.py
from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def home():
    return {"message": "Welcome to my FastAPI!"}

@app.get("/items/{item_id}")
def get_item(item_id: int, q: str = None):
    return {"item_id": item_id, "query": q}

▶️ Run it:

uvicorn fastapi_app:app --reload

Visit:

  • http://127.0.0.1:8000/
  • http://127.0.0.1:8000/items/10?q=test

And best part —
📘 Auto docs:

  • Swagger UI → http://127.0.0.1:8000/docs
  • ReDoc → http://127.0.0.1:8000/redoc

⚔️ Flask vs FastAPI Comparison

FeatureFlaskFastAPI
TypeMicro web frameworkModern async API framework
PerformanceSlower (sync)Much faster (async)
Data ValidationManualAutomatic (via Pydantic)
Auto Docs❌ No✅ Yes (/docs)
Ease for REST APIsGoodExcellent
Best Use CaseSmall/simple APIsModern microservices, AI/ML APIs

Verdict:

  • If you’re learning or doing small projects → Flask is great.
  • For production-grade, modern API development (especially for AI, data apps, or async systems) → FastAPI is the best choice.

Now we extend this example to include a POST API (for adding new items to a list/dictionary in memory)?
It’ll show how data is sent via JSON to the backend — a core REST concept.

Excellent 👌 — Let’s now extend both Flask and FastAPI examples to include a POST API that accepts JSON data and adds a new item to an in-memory list (or dictionary).

This shows how data flows from client → API → backend storage (list) — a key concept in REST.


🧩 Example Goal:

  • Maintain a list of items
  • GET /items → returns all items
  • POST /items → add a new item (sent as JSON)

🐍 1️⃣ Flask Example (with POST)

# flask_post_api.py
from flask import Flask, jsonify, request

app = Flask(__name__)

# In-memory data store
items = [
    {"id": 1, "name": "Pen", "price": 10},
    {"id": 2, "name": "Notebook", "price": 50}
]

@app.route('/items', methods=['GET'])
def get_items():
    return jsonify(items)

@app.route('/items', methods=['POST'])
def add_item():
    data = request.get_json()
    new_item = {
        "id": len(items) + 1,
        "name": data["name"],
        "price": data["price"]
    }
    items.append(new_item)
    return jsonify({"message": "Item added successfully", "item": new_item}), 201

if __name__ == '__main__':
    app.run(debug=True)

▶️ Run:

python flask_post_api.py

Test via curl or Postman:

# GET all items
curl http://127.0.0.1:5000/items

# POST new item
curl -X POST http://127.0.0.1:5000/items \
     -H "Content-Type: application/json" \
     -d '{"name": "Pencil", "price": 5}'

2️⃣ FastAPI Example (with POST)

# fastapi_post_api.py
from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

# In-memory data store
items = [
    {"id": 1, "name": "Pen", "price": 10},
    {"id": 2, "name": "Notebook", "price": 50}
]

# Define request body structure
class Item(BaseModel):
    name: str
    price: float

@app.get("/items")
def get_items():
    return items

@app.post("/items")
def add_item(item: Item):
    new_item = {
        "id": len(items) + 1,
        "name": item.name,
        "price": item.price
    }
    items.append(new_item)
    return {"message": "Item added successfully", "item": new_item}

▶️ Run:

uvicorn fastapi_post_api:app --reload

Test via browser or Postman:

  • GET http://127.0.0.1:8000/items
  • POST http://127.0.0.1:8000/items
    JSON Body: { "name": "Pencil", "price": 5 }

✅ Auto-docs:

  • Swagger UI: http://127.0.0.1:8000/docs
  • ReDoc: http://127.0.0.1:8000/redoc

⚔️ Flask vs FastAPI – POST Comparison

FeatureFlaskFastAPI
JSON Parsingrequest.get_json()Automatically handled
Input ValidationManual✅ via Pydantic models
Auto Docs❌ No/docs auto generated
Type HintsOptionalEnforced for clarity
SpeedSlowerFaster (async)

🧠 Summary

EndpointMethodDescription
/itemsGETFetch all items
/itemsPOSTAdd a new item via JSON

Now we add a PUT (update) and DELETE API next — so you get a complete CRUD (Create, Read, Update, Delete) example in both Flask and FastAPI

Perfect ✅ — now we’ll complete the picture by adding PUT (update) and DELETE endpoints — giving you a full CRUD API in both Flask and FastAPI.


🧱 CRUD Overview

OperationHTTP MethodDescriptionExample Endpoint
CreatePOSTAdd new item/items
ReadGETGet items/items
UpdatePUTModify existing item/items/{id}
DeleteDELETERemove item/items/{id}

🐍 1️⃣ Flask — Full CRUD Example

# flask_crud_api.py
from flask import Flask, jsonify, request

app = Flask(__name__)

# In-memory data
items = [
    {"id": 1, "name": "Pen", "price": 10},
    {"id": 2, "name": "Notebook", "price": 50}
]

# READ
@app.route('/items', methods=['GET'])
def get_items():
    return jsonify(items)

# CREATE
@app.route('/items', methods=['POST'])
def add_item():
    data = request.get_json()
    new_item = {
        "id": len(items) + 1,
        "name": data["name"],
        "price": data["price"]
    }
    items.append(new_item)
    return jsonify({"message": "Item added", "item": new_item}), 201

# UPDATE
@app.route('/items/<int:item_id>', methods=['PUT'])
def update_item(item_id):
    data = request.get_json()
    for item in items:
        if item["id"] == item_id:
            item["name"] = data.get("name", item["name"])
            item["price"] = data.get("price", item["price"])
            return jsonify({"message": "Item updated", "item": item})
    return jsonify({"error": "Item not found"}), 404

# DELETE
@app.route('/items/<int:item_id>', methods=['DELETE'])
def delete_item(item_id):
    for item in items:
        if item["id"] == item_id:
            items.remove(item)
            return jsonify({"message": f"Item {item_id} deleted"})
    return jsonify({"error": "Item not found"}), 404

if __name__ == '__main__':
    app.run(debug=True)

▶️ Run:

python flask_crud_api.py

2️⃣ FastAPI — Full CRUD Example

# fastapi_crud_api.py
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel

app = FastAPI()

# In-memory data
items = [
    {"id": 1, "name": "Pen", "price": 10},
    {"id": 2, "name": "Notebook", "price": 50}
]

# Request model
class Item(BaseModel):
    name: str
    price: float

# READ
@app.get("/items")
def get_items():
    return items

# CREATE
@app.post("/items")
def add_item(item: Item):
    new_item = {"id": len(items) + 1, "name": item.name, "price": item.price}
    items.append(new_item)
    return {"message": "Item added", "item": new_item}

# UPDATE
@app.put("/items/{item_id}")
def update_item(item_id: int, updated_item: Item):
    for item in items:
        if item["id"] == item_id:
            item["name"] = updated_item.name
            item["price"] = updated_item.price
            return {"message": "Item updated", "item": item}
    raise HTTPException(status_code=404, detail="Item not found")

# DELETE
@app.delete("/items/{item_id}")
def delete_item(item_id: int):
    for item in items:
        if item["id"] == item_id:
            items.remove(item)
            return {"message": f"Item {item_id} deleted"}
    raise HTTPException(status_code=404, detail="Item not found")

▶️ Run:

uvicorn fastapi_crud_api:app --reload

Test via browser or Postman:

  • GEThttp://127.0.0.1:8000/items
  • POST → Add a new item { "name": "Eraser", "price": 8 }
  • PUT → Update existing item { "name": "Blue Pen", "price": 12 }
  • DELETE → Remove item by ID
    e.g., DELETE /items/1

✅ Auto Docs:

  • http://127.0.0.1:8000/docs
  • http://127.0.0.1:8000/redoc

⚔️ Flask vs FastAPI — CRUD Comparison

FeatureFlaskFastAPI
SetupSimpleSlightly more setup (Pydantic)
ValidationManual✅ Auto via model
Error HandlingManual (if/else)✅ Built-in HTTPException
Docs UI❌ None/docs & /redoc
SpeedSynchronous✅ Async support
TypingOptional✅ Enforced

🧠 Summary

✅ You now have:

  • Flask CRUD API → Easy for beginners
  • FastAPI CRUD API → Modern, production-grade

Both can serve as a backend for React, mobile apps, or AI services.


Now i will show next how to connect this FastAPI CRUD with a real database (like SQLite) — so data persists even after restart?
That’s the next step to make this a real-world API.

Perfect 💪 — now you’re moving from in-memory (temporary) data to persistent storage (real database).
We’ll connect both Flask and FastAPI to a SQLite database, which is lightweight, file-based, and great for learning or small projects.


🧱 Overview

FrameworkORM/LibraryDB UsedDescription
FlaskSQLAlchemySQLiteClassic ORM for Flask
FastAPISQLModel (built on SQLAlchemy)SQLiteModern ORM, async-ready

🐍 1️⃣ Flask CRUD API with SQLite (SQLAlchemy)


📦 Install dependencies

pip install flask sqlalchemy

🧩 Flask Code

# flask_crud_db.py
from flask import Flask, request, jsonify
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)

# SQLite database configuration
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///items.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

db = SQLAlchemy(app)

# Model definition
class Item(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50), nullable=False)
    price = db.Column(db.Float, nullable=False)

    def to_dict(self):
        return {"id": self.id, "name": self.name, "price": self.price}

# Create database
with app.app_context():
    db.create_all()

# CREATE
@app.route('/items', methods=['POST'])
def add_item():
    data = request.get_json()
    new_item = Item(name=data['name'], price=data['price'])
    db.session.add(new_item)
    db.session.commit()
    return jsonify({"message": "Item added", "item": new_item.to_dict()}), 201

# READ
@app.route('/items', methods=['GET'])
def get_items():
    all_items = Item.query.all()
    return jsonify([item.to_dict() for item in all_items])

# UPDATE
@app.route('/items/<int:item_id>', methods=['PUT'])
def update_item(item_id):
    data = request.get_json()
    item = Item.query.get(item_id)
    if not item:
        return jsonify({"error": "Item not found"}), 404
    item.name = data.get('name', item.name)
    item.price = data.get('price', item.price)
    db.session.commit()
    return jsonify({"message": "Item updated", "item": item.to_dict()})

# DELETE
@app.route('/items/<int:item_id>', methods=['DELETE'])
def delete_item(item_id):
    item = Item.query.get(item_id)
    if not item:
        return jsonify({"error": "Item not found"}), 404
    db.session.delete(item)
    db.session.commit()
    return jsonify({"message": f"Item {item_id} deleted"})

if __name__ == '__main__':
    app.run(debug=True)

▶️ Run:

python flask_crud_db.py

🧠 SQLite file created:

A file named items.db will appear in your working directory — that’s your database.


2️⃣ FastAPI CRUD API with SQLite (SQLModel)


📦 Install dependencies

pip install fastapi uvicorn sqlmodel

🧩 FastAPI Code

# fastapi_crud_db.py
from fastapi import FastAPI, HTTPException
from sqlmodel import SQLModel, Field, Session, create_engine, select

# Define database and model
sqlite_url = "sqlite:///items.db"
engine = create_engine(sqlite_url, echo=True)

class Item(SQLModel, table=True):
    id: int | None = Field(default=None, primary_key=True)
    name: str
    price: float

# Create DB tables
SQLModel.metadata.create_all(engine)

app = FastAPI()

# CREATE
@app.post("/items")
def add_item(item: Item):
    with Session(engine) as session:
        session.add(item)
        session.commit()
        session.refresh(item)
        return {"message": "Item added", "item": item}

# READ
@app.get("/items")
def get_items():
    with Session(engine) as session:
        items = session.exec(select(Item)).all()
        return items

# UPDATE
@app.put("/items/{item_id}")
def update_item(item_id: int, updated_item: Item):
    with Session(engine) as session:
        item = session.get(Item, item_id)
        if not item:
            raise HTTPException(status_code=404, detail="Item not found")
        item.name = updated_item.name
        item.price = updated_item.price
        session.commit()
        session.refresh(item)
        return {"message": "Item updated", "item": item}

# DELETE
@app.delete("/items/{item_id}")
def delete_item(item_id: int):
    with Session(engine) as session:
        item = session.get(Item, item_id)
        if not item:
            raise HTTPException(status_code=404, detail="Item not found")
        session.delete(item)
        session.commit()
        return {"message": f"Item {item_id} deleted"}

▶️ Run:

uvicorn fastapi_crud_db:app --reload

Visit:

✅ Database file items.db will be created automatically.


⚔️ Flask vs FastAPI with DB — Comparison

FeatureFlask + SQLAlchemyFastAPI + SQLModel
DB ConnectionSQLAlchemy ORMSQLModel (built on SQLAlchemy)
Async Support❌ No✅ Optional
Schema ValidationManual✅ Automatic via type hints
Auto Docs❌ No/docs
Learning CurveEasySlightly steeper
Ideal UseTraditional Web AppsModern APIs / AI Backends

🧠 Summary

✅ You now know:

  • How to build CRUD APIs
  • How to store data persistently in SQLite
  • How to use ORM (Object Relational Mapping) in both Flask & FastAPI

Posted in

Leave a Reply

Your email address will not be published. Required fields are marked *