Skip to main content

flask-modelkit

Tests PyPI Docs Python Downloads/month Total downloads GitHub stars License: MIT

Composable model mixins for Flask-SQLAlchemy.

Documentation: anoziechibuike.github.io/FlaskModelKit

⭐ If flask-modelkit saves you from writing another base model, star it on GitHub. It helps other Flask developers find it.

Formerly published as FlaskSQLAlchemyBaseModel. See Migrating from FlaskSQLAlchemyBaseModel.

Most Flask projects end up writing the same base model: a UUID primary key, created_at/updated_at, save(), to_dict(), maybe soft delete. Each copy has its own subtle bugs. This package gives you those pieces as small mixins that you combine per model. The edge cases are handled and tested.

class Post(UUIDMixin, TimestampMixin, SoftDeleteMixin, CRUDMixin, SerializerMixin, db.Model):
    title = db.Column(db.String(200), nullable=False)

Features

  • Pick what you need. UUID or integer keys, timestamps, soft delete, CRUD helpers and serialisation are separate mixins. BaseModelMixin bundles the common set.
  • Soft delete that actually hides rows. Deleted rows are filtered out of every ORM query: helpers, Model.query, db.select(), session.get() and relationship loads.
  • Hidden and protected fields. Mark a column hidden (never sent to the client), protected (never set from client input) or both, right where you declare it.
  • Safe updates. update(request.json) only sets mapped columns and never touches id, timestamps or any protected field.
  • Create from request data in one line. create_or_abort(request.json) drops unsafe keys, answers 400 naming every missing field, and 409 naming a duplicate unique field.
  • Safe serialisation. to_dict() never outputs hidden fields (such as password hashes), limits relationship depth, never loops on back_populates, and returns JSON-ready output on request.
  • Efficient queries. Counts and existence checks run in SQL. Pagination is stably ordered.
  • Migration-friendly. Defaults are generated in Python, so Flask-Migrate/Alembic produces clean migrations with no spurious diffs.
  • Typed. Ships py.typed, and class methods return your model type.
  • Works with your own db. No global SQLAlchemy() is forced on you.

Requires Python 3.10+, Flask 3, Flask-SQLAlchemy 3.1+ and SQLAlchemy 2.0.16+.

Install

pip install flask-modelkit

Quick start

from flask import Flask, jsonify, request
from flask_sqlalchemy import SQLAlchemy
from flask_modelkit import BaseModelMixin, protected_column, secret_column

db = SQLAlchemy()


class User(BaseModelMixin, db.Model):          # mixins go before db.Model
    name = db.Column(db.String(50), nullable=False)
    email = db.Column(db.String(100), unique=True, nullable=False)
    is_admin = protected_column(db.Boolean, default=False)   # input can't set it
    password_hash = secret_column(db.String(200))            # never read out, never written in


app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///app.db"
db.init_app(app)

with app.app_context():
    db.create_all()                             # or Flask-Migrate, see https://anoziechibuike.github.io/FlaskModelKit/#migrations


@app.post("/users")
def create_user():
    # 400 if name/email are missing, 409 if the email is taken, unknown keys dropped
    user = User.create_or_abort(request.get_json(silent=True))
    return jsonify(user.to_dict(json_safe=True)), 201


@app.patch("/users/<id>")
def update_user(id):
    user = User.get_or_404(id)
    user.update(request.json)                   # id, timestamps, is_admin, password_hash can't be set
    return jsonify(user.to_dict(json_safe=True))


@app.get("/users")
def list_users():
    page = User.paginate(page=request.args.get("page", 1, type=int), per_page=20)
    page["items"] = [u.to_dict(json_safe=True) for u in page["items"]]
    return jsonify(page)

Don't have a db yet? Use the bundled one:

from flask_modelkit import db, BaseModel

class User(BaseModel):
    name = db.Column(db.String(50))

Documentation

The full documentation is at anoziechibuike.github.io/FlaskModelKit.

Guide
Quick start A complete app in four steps
Mixins Every mixin, an interactive builder, and the one ordering rule
Creating & updating create, create_or_abort, save, update, transactions
Reading & filtering get, filters, counts, pagination, custom queries
Hidden vs protected Controlling what goes out to and comes in from the client
Serialisation to_dict(), depth, JSON output
Soft delete How rows are hidden, including deleted rows, restoring
Migrations Flask-Migrate/Alembic, adding mixins to existing tables
Project examples A blog API, a shop checkout, lookup tables
API reference Every public name

Use with AI agents

AI coding assistants don't know this package's rules: mixins before db.Model, create_or_abort() for request data, secret_column() for password hashes. AGENT.md spells them out. Add it to your project once, from the project root:

# Claude Code: save it, then import it from CLAUDE.md
mkdir -p .claude && curl -fsSL https://anoziechibuike.github.io/FlaskModelKit/AGENT.md -o .claude/flask-modelkit.md
echo "@.claude/flask-modelkit.md" >> CLAUDE.md

# Cursor: a project rule attached to Python files
mkdir -p .cursor/rules
{ printf -- '---\ndescription: How to use flask-modelkit models, fields and endpoints\nglobs: **/*.py\nalwaysApply: false\n---\n\n'
  curl -fsSL https://anoziechibuike.github.io/FlaskModelKit/AGENT.md; } > .cursor/rules/flask-modelkit.mdc

# GitHub Copilot: path-specific instructions for Python files
mkdir -p .github/instructions
{ printf -- '---\napplyTo: "**/*.py"\n---\n\n'
  curl -fsSL https://anoziechibuike.github.io/FlaskModelKit/AGENT.md; } > .github/instructions/flask-modelkit.instructions.md

# Codex, Jules, Amp, Zed and other AGENTS.md readers (Gemini CLI: GEMINI.md)
curl -fsSL https://anoziechibuike.github.io/FlaskModelKit/AGENT.md >> AGENTS.md

In a chat assistant, say: "Read https://anoziechibuike.github.io/FlaskModelKit/AGENT.md and follow it for all flask-modelkit code." To pin the rules to your installed version, download from the release tag instead, for example https://raw.githubusercontent.com/AnozieChibuike/FlaskModelKit/v1.0.0/AGENT.md. See Use with AI agents for details.

Migrating from FlaskSQLAlchemyBaseModel

flask-modelkit 1.0 continues FlaskSQLAlchemyBaseModel under a new name.

pip uninstall FlaskSQLAlchemyBaseModel
pip install flask-modelkit

Then replace the import:

# before
from flasksqlalchemybasemodel import BaseModel, db
# after
from flask_modelkit import BaseModel, db

The old flasksqlalchemybasemodel.src module is gone; import from flask_modelkit directly. The columns the mixins create are unchanged, so no database migration is needed. See CHANGELOG.md for everything else that changed.

Development

pip install -e . pytest alembic
pytest

CI runs the suite on Python 3.10–3.13 and against the minimum supported dependency versions.

Star history

flask-modelkit star history

More numbers, including downloads, live on the Community & stats page.

License

MIT

Metadata

Release files for flask-modelkit 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for flask-modelkit 1.0.0
File Size Uploaded Provenance Actions
flask_modelkit-1.0.0.tar.gz 15.6 kB With provenance Details for flask_modelkit-1.0.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for flask-modelkit 1.0.0
File Interpreter ABI Platform Actions
flask_modelkit-1.0.0-py3-none-any.whl Python 3 none any Details for flask_modelkit-1.0.0-py3-none-any.whl

Total release size: 29.8 kB

Release files / flask_modelkit-1.0.0.tar.gz

Download URL flask_modelkit-1.0.0.tar.gz
Size 15.6 kB
Tags Source
SHA-256 checksum
How to use checksums
8f7c45d2bf073e50b45da0f6f0c0d9a4ebddefc86163f60c86e483f5c3dd626a
BLAKE2b-256 checksum
How to use checksums
96393ad375de57e8170eb63c029d93cf074b7c307d8d159d3fa8ee804a71b2dc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 7, 2026.

Transparency log

Release files / flask_modelkit-1.0.0-py3-none-any.whl

Download URL flask_modelkit-1.0.0-py3-none-any.whl
Size 14.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ed7d5d344a3620302eb3238930b8c4b249579081c02e04a286b278afe86c5f1b
BLAKE2b-256 checksum
How to use checksums
5fac12faf15e6f676bb4423ac7dfd83edc1d9a376acdb8af6d05e7f11c386991
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 7, 2026.

Transparency log

Security for flask-modelkit 1.0.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for flask_modelkit-1.0.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 7, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page