Dynamic API generator from JSON models with automatic schema inference.
Project description
AutoRESTify
The High-Performance Runtime Engine for Persistent REST APIs.
AutoRESTify transforms JSON collections into complete, persistent, and secure REST APIs at runtime — no code generation, no ORM, no boilerplate.
🆕 What's New in v2.0 — Zero-ORM Stack
The entire dependency tree was replaced with minimal, targeted libraries:
| Removed | Replaced by | Savings |
|---|---|---|
| FastAPI + pydantic + pydantic_core | Starlette | −10 MB |
| SQLAlchemy ORM | raw aiosqlite SQL |
−22 MB |
| Total install footprint | ~3.5 MB | −30 MB (−90%) |
| Import time | ~80 ms | −400 ms (−83%) |
Additional gains:
table_exists()is O(1) in-memory lookup — zero DB round-trips per request- No ORM serialization overhead — raw
dictfrom SQLite cursor - Test suite runs in 0.30 s (was 0.99 s)
Breaking change:
create_router()now returns a StarletteRouterinstead of a FastAPIAPIRouter. For FastAPI projects, mount the Starlette app withfastapi_app.mount("/api", create_app()).
🚀 Features
- Dynamic route generation from JSON uploads
- Automatic schema inference (no schema definition required)
- Async SQLite persistence via
aiosqlite(non-blocking I/O) - Full CRUD support with paginated list responses
- Filtering, pagination, and ordering on list endpoints
- RBAC with Bearer-token authentication
- Multi-tenant isolation (row-level, pluggable resolver)
- Pluggable security architecture (custom auth/policy via ABCs)
- In-memory database for test isolation (
sqlite:///:memory:) - Lightweight: only
starlette+aiosqlitedependencies
📦 Installation
pip install autorestify
With uvicorn included:
pip install autorestify[server]
Local development:
git clone https://github.com/MikaelMartins/autorestify.git
cd autorestify
pip install -e ".[server]"
⚡ Quick Start
from autorestify import create_app
import uvicorn
app = create_app() # Starlette ASGI app, SQLite at ./autorestify.db
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000)
uvicorn main:app --reload
create_app() accepts optional database, security, and tenant_resolver arguments for full customization.
📤 Uploading a collection
Send a JSON payload to /upload to register a collection and its documents:
POST /upload
Content-Type: application/json
{
"collection": "clientes",
"documents": [
{"name": "Ana", "age": 30},
{"name": "Carlos", "age": 25}
]
}
AutoRESTify infers the schema and creates the table. The following routes are immediately available:
GET /clientes → list (paginated)
GET /clientes/{id} → single item
POST /clientes → create
PUT /clientes/{id} → update
DELETE /clientes/{id} → delete
🔍 Filtering, Pagination & Ordering
The GET /{collection} endpoint supports query parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
page |
int ≥ 1 | 1 |
Page number |
page_size |
int 1–1000 | 20 |
Items per page |
order_by |
string | — | Field name to sort by |
order |
asc | desc |
asc |
Sort direction |
<field>=<value> |
any | — | Exact-match filter |
GET /clientes?age=30&order_by=name&order=asc&page=1&page_size=10
Response envelope:
{
"data": [...],
"total": 42,
"page": 1,
"page_size": 10,
"pages": 5
}
🔐 RBAC (Role-Based Access Control)
Fine-grained access control via three building blocks:
| Class | Role |
|---|---|
RBACUser |
Carries the user's name and list of roles |
RBACPolicy |
Maps (role, resource) → {read, write, delete} |
TokenAuthProvider |
Resolves Authorization: Bearer <token> to an RBACUser |
from autorestify import create_app, Database
from autorestify.core.rbac import RBACUser, RBACPolicy, TokenAuthProvider
from autorestify.core.security import SecurityManager
policy = RBACPolicy({
"admin": {"*": {"read", "write", "delete"}},
"reader": {"*": {"read"}},
"editor": {"products": {"read", "write"}},
})
auth = TokenAuthProvider({
"tok-alice": RBACUser(name="alice", roles=["admin"]),
"tok-bob": RBACUser(name="bob", roles=["reader"]),
})
security = SecurityManager(auth_provider=auth, access_policy=policy)
app = create_app(security=security)
Permissions can be updated at runtime via policy.grant(role, resource, actions) and policy.revoke(role, resource).
🏢 Multi-tenant Architecture
Row-level tenancy is built into every collection. All requests are automatically scoped to a tenant — no manual filtering needed.
from autorestify import create_app, Database, HeaderTenantResolver
app = create_app(
database=Database(),
tenant_resolver=HeaderTenantResolver(), # reads X-Tenant-ID header
)
| Resolver | Behaviour |
|---|---|
HeaderTenantResolver(header="X-Tenant-ID") |
Reads header; defaults to "default" if absent |
SingleTenantResolver() |
Always "default" — zero-config (library default) |
- Every collection gains an indexed
tenant_idcolumn automatically. GET,POST,PUT,DELETEare all scoped — cross-tenant access returns 404.tenant_id,id, andcreated_atare write-protected and cannot be overwritten viaPUT.- Filtering, pagination, and ordering all operate within the caller's tenant scope.
🔗 FastAPI Integration
create_app() returns a standard Starlette ASGI app that can be mounted on any ASGI framework:
from fastapi import FastAPI
from autorestify import create_app, Database
fastapi_app = FastAPI()
fastapi_app.mount("/api", create_app(database=Database()))
🧠 Architecture
AutoRESTify is built exclusively on:
- Starlette — HTTP routing and request/response layer
- aiosqlite — async SQLite persistence with raw SQL
Core modules:
autorestify/
api/
router_factory.py # Starlette Router with all handlers
app_factory.py # Starlette app wrapper
core/
schema_inference.py # JSON → SQL type mapping
security.py # AuthProvider / AccessPolicy ABCs
rbac.py # RBACUser, RBACPolicy, TokenAuthProvider
tenant.py # TenantResolver, HeaderTenantResolver, SingleTenantResolver
storage/
base.py # async Database (aiosqlite wrapper)
repository.py # raw SQL CRUD with tenant scoping
🧪 Running Tests
pytest -v
With coverage:
pytest --cov=autorestify --cov-report=term-missing
Tests use in-memory SQLite for full isolation:
from autorestify import create_app, Database
from starlette.testclient import TestClient
client = TestClient(create_app(database=Database("sqlite:///:memory:")))
🛠 Development Setup
python -m venv .venv
source .venv/bin/activate
pip install -e ".[server]"
pytest -v
🗺 Roadmap
- ✅ Filtering, pagination, and ordering
- ✅ Async storage engine (aiosqlite)
- ✅ RBAC with Bearer-token authentication
- ✅ Multi-tenant architecture (row-level)
- ✅ Zero-ORM stack (Starlette + aiosqlite only)
📜 License
MIT License
👨💻 Author
Mikael Aurio Martins — Software Developer
Project details
Release history Release notifications | RSS feed
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 autorestify-2.0.0.tar.gz.
File metadata
- Download URL: autorestify-2.0.0.tar.gz
- Upload date:
- Size: 19.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c13cad20c044ec020c5fb5c3f1bc5c0e0780c7e7783a5850b06ee2ecf9f26467
|
|
| MD5 |
ab374ba8e96ba9c9aebe853d661f5366
|
|
| BLAKE2b-256 |
9853e32aaa7deee8f8f5862e7566d4e908a450325da578fa99d2be3920c66780
|
File details
Details for the file autorestify-2.0.0-py3-none-any.whl.
File metadata
- Download URL: autorestify-2.0.0-py3-none-any.whl
- Upload date:
- Size: 16.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a2228908659f7a086516a2541393bdbe350a7ef0720fe2af8a94af9f58b162f1
|
|
| MD5 |
bd509ca7ec13af6ebad6364980663f2e
|
|
| BLAKE2b-256 |
289ee841dbaddd21936972ec1bd53ce54a1515e91326f0c3ce324b73a7b07992
|