Jetio
The Zero-Boilerplate Python Framework for Rapid API Development
Jetio is a modern, high-performance Python web framework designed to transform your SQLAlchemy models directly into fully-featured, production-ready REST APIs with minimal code. Stop writing boilerplate and start building what matters.
Instalation
pip install jetio
Configuration
If your app uses JWT auth (create_access_token/decode_access_token,
which is what jetio-auth builds
on), set SECRET_KEY before issuing or validating any token. There's no
default: a fixed value shipped in jetio's own published source would be
public, not secret, and anyone could forge a valid token for any user.
Apps that don't use JWT auth (plain CRUD APIs, your own auth scheme) don't
need this set at all.
export SECRET_KEY=$(openssl rand -hex 32)
See jetio.config.Settings for the rest of the available configuration
(database URL, mail settings, etc.).
Key Features
- Model-Driven APIs: Use standard SQLAlchemy models as your single source of truth for your database, validation, and API serialization.
- Automatic CRUD: Instantly generate robust Create, Read, Update, and Delete endpoints for any model with a single line of code.
- Secure by Design: Easily secure your auto-generated endpoints with a single flag and plug in your own authentication logic.
- Async First: Built from the ground up on an async core (powered by Starlette) for maximum performance and scalability.
- Automatic Docs: Get interactive and functional Swagger UI out of the box.
- Flexible & Familiar: Escape the generator whenever you need to. Use familiar decorator-based routing for custom endpoints, giving you the best of both worlds.
- Visit Jetio Framework You can deliver more than 500 times faster with Jetio - see how it works.
- GitHub Pages Documentation: Browse the Jetio docs on GitHub Pages
- Jetio Framework oneBenchmark Results: We compared Jetio speed with Flask & FastAPI See the result for yourself.
Simple Hello Jetio app
from jetio import Jetio
app = Jetio()
@app.route('/')
async def hello():
return "Hello, Jetio!"
if __name__ == '__main__':
app.run()
Activating swagger-UI for Hello Jetio app
from jetio import Jetio, add_swagger_ui # add the add_swagger_ui
app = Jetio()
add_swagger_ui(app) # generates the swagger-UI
@app.route('/')
async def hello():
return "Hello, Jetio!"
if __name__ == '__main__':
app.run()
Example - Using models in separate file
# model.py
from sqlalchemy.orm import Mapped
from jetio import JetioModel
class User(JetioModel):
username: Mapped[str]
email: Mapped[str]
class Minister(JetioModel):
first_name: Mapped[str]
last_name: Mapped[str]
Get Jetio to make your app with imported models
# app.py
from jetio import Jetio, CrudRouter, add_swagger_ui
from model import User, Minister
app = Jetio()
add_swagger_ui(app)
# Generate 5 CRUD routes per model
CrudRouter(model=User).register_routes(app)
CrudRouter(model=Minister).register_routes(app)
if __name__ == "__main__":
app.run()
Database setup
Use your preferred DB tool.
or for quick dev environment, you can also change your app.py above to:
# app.py
from jetio import Jetio, CrudRouter, add_swagger_ui, Base, engine
from model import User, Minister
import asyncio
app = Jetio()
add_swagger_ui(app)
# Generate 5 CRUD routes per model
CrudRouter(model=User).register_routes(app)
CrudRouter(model=Minister).register_routes(app)
# --- Database and Server Startup ---
async def create_db_and_tables():
async with engine.begin() as conn:
await conn.run_sync(Base.metadata.create_all)
print("Database tables created.")
if __name__ == "__main__":
asyncio.run(create_db_and_tables())
app.run()
Simplified Single File Setup
You could simply have the model classes in the main file as follows.
from jetio import Jetio, CrudRouter, JetioModel, add_swagger_ui, Base, engine
import asyncio
from sqlalchemy.orm import Mapped
class Staff(JetioModel):
username: Mapped[str]
email: Mapped[str]
class Report(JetioModel):
title: Mapped[str]
content: Mapped[str]
app = Jetio()
add_swagger_ui(app)
# Generate 5 CRUD routes per model
CrudRouter(model=Staff).register_routes(app)
CrudRouter(model=Report).register_routes(app)
# --- Database and Server Startup ---
async def create_db_and_tables():
async with engine.begin() as conn:
await conn.run_sync(Base.metadata.create_all)
print("Database tables created.")
if __name__ == "__main__":
asyncio.run(create_db_and_tables())
app.run()
The CrudRouter is a powerful tool that allows you to cleanly declare your API's functionality, saving you from writing hundreds of lines of boilerplate code.
Relationship
Jetio relationship prevents N+1 Query - Built-in relationship loading using SQLAlchemy's selectinload() prevents performance bottlenecks automatically.
One-to-many Relationship
# app.py
from jetio import Jetio, CrudRouter, JetioModel, add_swagger_ui, Base, engine
from sqlalchemy import ForeignKey
from sqlalchemy.orm import Mapped, mapped_column, relationship
from typing import List
import asyncio
#===================================================================
# Models - you can have this in a separate file, however you desire.
#===================================================================
class Author(JetioModel):
__tablename__ = 'authors'
name: Mapped[str]
email: Mapped[str]
books: Mapped[List["Book"]] = relationship(back_populates="author", cascade="all, delete-orphan")
class Book(JetioModel):
__tablename__ = 'books'
title: Mapped[str]
isbn: Mapped[str]
author_id: Mapped[int] = mapped_column(ForeignKey("authors.id"))
author: Mapped["Author"] = relationship(back_populates="books")
#===========================================
# end of models
# =========================================
app = Jetio()
add_swagger_ui(app)
CrudRouter(model=Author, load_relationships=["books"]).register_routes(app)
CrudRouter(model=Book, load_relationships=["author"]).register_routes(app)
async def init_db():
async with engine.begin() as conn:
await conn.run_sync(Base.metadata.create_all)
print("✅ Database initialized")
if __name__ == "__main__":
asyncio.run(init_db())
print("🚀 Server running at http://localhost:8000")
print("📚 API docs at http://localhost:8000/docs")
app.run()
Our Philosophy
Boilerplate code is a barrier between a great idea and a finished product. Modern development should be about defining your logic, not endlessly reimplementing the plumbing. Jetio believes in convention over configuration and the power of using a single source of truth. Your data model is your API.
Contributing
Contributions are welcome! Please feel free to submit a pull request, open an issue, or provide feedback.
License
This project is licensed under the BSD 3-Clause license.
Release files for jetio 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 | |
|---|---|---|---|
| jetio-2.0.0.tar.gz | 40.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| jetio-2.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 73.9 kB
Release files / jetio-2.0.0.tar.gz
| Download URL | jetio-2.0.0.tar.gz |
|---|---|
| Size | 40.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5058da007759123bb5d9024bd3cf8b89876df8e76922d0d7b3eab1047e1fd10b
|
|
BLAKE2b-256 checksum How to use checksums |
eb5fc25b61b86c4bb1543282ac9e7107d1b17608a067c61afb2f9814f347a9b0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.10
|
Release files / jetio-2.0.0-py3-none-any.whl
| Download URL | jetio-2.0.0-py3-none-any.whl |
|---|---|
| Size | 33.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2df76bf193bcd9067a5cf27de52621f7af6b5ee60aa49470f3d980ac4ef4533f
|
|
BLAKE2b-256 checksum How to use checksums |
5cfcd41b11526297f10a352ac01953fcf19ba12d6ee88eaf48e32fa11dcfecf5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.10
|