Skip to main content

🌿 mossify

PyPI - Version PyPI - Python Version PyPI - License PyPI - Downloads GitHub Actions Workflow Status

Mossify is a simple, organic framework that wraps FastAPI and SQLModel to give you automatic CRUD routes and intelligent caching – with almost zero boilerplate.

"Mossify your backend. Simple, organic, and fully covered."


🚀 Quick Start

pip install mossify
from mossify import Mossify
from sqlmodel import SQLModel, Field
from typing import Optional


class Product(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    name: str
    price: float


app = Mossify(database_url="sqlite:///database.db")
app.register_model(Product)

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

That's it! You now have a fully functional API with:

Method Endpoint Description
GET /products List (paginated)
POST /products Create
GET /products/count Count
GET /products/{id} Get by ID
PATCH /products/{id} Partial update
PUT /products/{id} Full replacement
DELETE /products/{id} Delete

All read endpoints are automatically cached (configurable TTL). Cache is invalidated on any write operation.


✨ Features

  • 🔌 Zero boilerplate – define your models, call register_model(), and go.
  • FastAPI + SQLModel – fully async, modern, and type-safe.
  • 🧠 Intelligent caching – automatic TTL-based cache via diskcache for GET endpoints.
  • 🔄 Automatic invalidation – cache cleared on POST, PUT, PATCH, DELETE.
  • 📄 Paginated listing – built-in page/size query params with configurable limits.
  • 🔢 Auto count endpointGET /{models}/count returns total records.
  • 🗃️ Async queue mode – high-throughput POST with batch inserts and configurable flush interval.
  • 🔧 Multi‑worker ready – scales with uvicorn workers out of the box.
  • 📦 Built‑in OpenAPI – interactive docs at /docs and /redoc.
  • 🛡️ Auth module – JWT authentication with register, login, protected routes, and per-model auth.
  • 🖥️ CLI toolmossify --version, mossify --about, mossify hello.
  • 🎛️ Granular control – exclude specific endpoints, set custom prefixes, override cache TTL per route.

📦 Installation

pip install mossify

Or with uv:

uv pip install mossify

🧑‍💻 Usage

Basic setup

from mossify import Mossify
from sqlmodel import SQLModel, Field
from typing import Optional


class Item(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    name: str
    description: Optional[str] = None


app = Mossify(
    database_url="sqlite:///items.db",
    title="My API",
    cache_ttl=300,       # 5 minutes default cache
)

app.register_model(Item, tags=["Items"])

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8000)

Configuration

Mossify() accepts:

Parameter Default Description
database_url "sqlite:///mossify.db" Database connection URL
database_models None Optional list of models to create tables
title "Mossify API" FastAPI title
description "..." FastAPI description
version "0.1.4" API version
cache_dir ".mossify_cache" Directory for diskcache
cache_ttl 500 Default cache TTL (seconds)
openapi_url "/openapi.json" OpenAPI schema path
docs_url "/docs" Swagger UI path
redoc_url "/redoc" ReDoc path
enable_auth False Enable built-in auth routes and User model

You can also pass any additional **fastapi_kwargs that FastAPI() accepts.

Model registration

app.register_model() accepts:

Parameter Default Description
prefix Auto (/classname + s) URL prefix
exclude [] List of methods to skip ("list", "create", "read", "update", "put", "delete", "count"`)
pagination_default_size 20 Default items per page
pagination_max_size 100 Maximum items per page
async_mode False Enable async queue for POST
batch_size 1000 Batch size for queue flush
flush_interval 5.0 Max seconds before queue flush (seconds)
auth_dep None Auth dependency to protect all routes of this model (from app.auth_dep)
**route_kwargs Extra args passed to FastAPI route (e.g. tags, dependencies)

Async queue mode

For high-load write scenarios, enable async_mode:

app.register_model(
    Product,
    async_mode=True,
    batch_size=5_000,      # flush every 5000 items
    flush_interval=5.0,    # or every 5 seconds
)

POST requests return 202 Accepted immediately with a temporary ID. Items are inserted in batches by a background worker.

Pagination

List endpoints support pagination out of the box:

GET /products?page=1&size=20

Response headers include X-Total-Count with the total number of records.

Excluding endpoints

Skip specific operations:

app.register_model(
    Product,
    exclude=["put", "delete"],   # disable PUT and DELETE
)

Custom route prefix

app.register_model(
    Product,
    prefix="/api/v1/products",
)

Relationship example

Models with foreign keys and relationships work seamlessly:

class Category(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    name: str = Field(index=True, unique=True)
    products: List["Product"] = Relationship(back_populates="category")


class Product(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    name: str
    category_id: Optional[int] = Field(default=None, foreign_key="category.id")
    category: Optional[Category] = Relationship(back_populates="products")


app = Mossify(database_url="sqlite:///ecommerce.db", database_models=[Category, Product])
app.register_model(Category, tags=["Categories"])
app.register_model(Product, tags=["Products"])

🖥️ CLI

mossify --version     # Show version
mossify --about       # Show creator info
mossify hello         # Say hello
mossify hello --name Mossify  # Custom greeting

🛡️ Auth Module

Mossify comes with a built-in auth module using JWT and pbkdf2_sha256 (via passlib).

Quick start with auth

Enable auth with a single flag:

from mossify import Mossify
from sqlmodel import SQLModel, Field
from typing import Optional
from fastapi import Depends


class Product(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    name: str
    price: float


app = Mossify(
    database_url="sqlite:///app.db",
    database_models=[Product],
    enable_auth=True,                  # registers /auth/* routes + User model
)

app.register_model(
    Product,
    async_mode=True,
    batch_size=5_000,
    flush_interval=5.0,
    tags=["Products"],
    auth_dep=app.auth_dep,             # protects all Product CRUD routes
)

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

Auth endpoints

Method Endpoint Description
POST /auth/register Create a new user
POST /auth/login Get JWT token
GET /auth/me Get current user (protected)

Protecting specific models

Pass auth_dep=app.auth_dep to register_model() to require authentication on all CRUD routes of that model. Models registered without auth_dep remain public.

Manual setup

If you need more control, import directly:

from mossify import Mossify
from mossify.core.auth import register_auth_routes, User
from mossify.core.database import DatabaseManager

app = Mossify(database_url="sqlite:///app.db", database_models=[User])

db_manager = DatabaseManager("sqlite:///app.db")
get_current_user = register_auth_routes(app, db_manager)

🧑‍💻 Development

git clone https://github.com/Luiz-Trindade/mossify.git
cd mossify
uv venv
source .venv/bin/activate
uv sync
pytest tests/

📄 License

MIT © Luiz Gabriel Magalhães Trindade


🤝 Contributing

Contributions, issues, and feature requests are welcome! Feel free to check the issues page or open a pull request.


🙏 Acknowledgements

Built on top of the amazing FastAPI and SQLModel.


Made with 🌿 and ❤️

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mossify-0.1.6.tar.gz (19.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mossify-0.1.6-py3-none-any.whl (19.4 kB view details)

Uploaded Python 3

File details

Details for the file mossify-0.1.6.tar.gz.

File metadata

  • Download URL: mossify-0.1.6.tar.gz
  • Upload date:
  • Size: 19.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.27 {"installer":{"name":"uv","version":"0.11.27","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for mossify-0.1.6.tar.gz
Algorithm Hash digest
SHA256 396ea38501c253461ab6e3b31a597e008f3eb3b903c997237d3f0ed537e63a4f
MD5 8f8cf6462ff2c93c6b3395864b60f807
BLAKE2b-256 7731da39e0b99658fdcbd023027e407e52e5c0bfa1f855466e35fddb1084c86f

See more details on using hashes here.

File details

Details for the file mossify-0.1.6-py3-none-any.whl.

File metadata

  • Download URL: mossify-0.1.6-py3-none-any.whl
  • Upload date:
  • Size: 19.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.27 {"installer":{"name":"uv","version":"0.11.27","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for mossify-0.1.6-py3-none-any.whl
Algorithm Hash digest
SHA256 e2a9583a42b99dd13bc8d2956a6022c913d5884ffa573f3e1772cac332aab819
MD5 28a2d15b0ca756c0a178038e17b2e40c
BLAKE2b-256 2bb991734f492690412e076273111feb6029efe6fc90d83160e5009f5c4f2e0e

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.1.6 This release

2 files

0.1.5

2 files

0.1.4

2 files

0.1.3

2 files

0.1.2

2 files

0.1.1

2 files

0.1.0

2 files

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