🌿 mossify
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
diskcachefor GET endpoints. - 🔄 Automatic invalidation – cache cleared on POST, PUT, PATCH, DELETE.
- 📄 Paginated listing – built-in
page/sizequery params with configurable limits. - 🔢 Auto count endpoint –
GET /{models}/countreturns total records. - 🗃️ Async queue mode – high-throughput POST with batch inserts and configurable flush interval.
- 🔧 Multi‑worker ready – scales with
uvicornworkers out of the box. - 📦 Built‑in OpenAPI – interactive docs at
/docsand/redoc. - 🛡️ Auth module – JWT authentication with register, login, protected routes, and per-model auth.
- 🖥️ CLI tool –
mossify --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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mossify-0.1.5.tar.gz.
File metadata
- Download URL: mossify-0.1.5.tar.gz
- Upload date:
- Size: 18.0 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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
012a5c79ebd250d3ea81f28d381f35e341c6014dd49cc4279cebbeb6588415ef
|
|
| MD5 |
9018464ae5fadd1c72d1eacabb58f32b
|
|
| BLAKE2b-256 |
0f1d5990020c2c60310cec6224144e44363b30cd4bbf48542657e8f9596623eb
|
File details
Details for the file mossify-0.1.5-py3-none-any.whl.
File metadata
- Download URL: mossify-0.1.5-py3-none-any.whl
- Upload date:
- Size: 17.7 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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8a5d330cd93b4f7dc3166840440d08202e52a92f7bbac313869333d70703267a
|
|
| MD5 |
32254af754e81ec506e91e695686986c
|
|
| BLAKE2b-256 |
9bac9784ac953e460a287e09dd7f78459ddd6e16452f155d119c6dd71da73b91
|