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
Metadata
Release files for autorestify 2.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| autorestify-2.0.0.tar.gz | 19.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| autorestify-2.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 36.2 kB
Release files / autorestify-2.0.0.tar.gz
| Download URL | autorestify-2.0.0.tar.gz |
|---|---|
| Size | 19.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c13cad20c044ec020c5fb5c3f1bc5c0e0780c7e7783a5850b06ee2ecf9f26467
|
|
BLAKE2b-256 checksum How to use checksums |
9853e32aaa7deee8f8f5862e7566d4e908a450325da578fa99d2be3920c66780
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.2
|
Release files / autorestify-2.0.0-py3-none-any.whl
| Download URL | autorestify-2.0.0-py3-none-any.whl |
|---|---|
| Size | 16.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a2228908659f7a086516a2541393bdbe350a7ef0720fe2af8a94af9f58b162f1
|
|
BLAKE2b-256 checksum How to use checksums |
289ee841dbaddd21936972ec1bd53ce54a1515e91326f0c3ce324b73a7b07992
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.2
|