Rango API Framework
A modern Python web framework built on Starlette with Django-like features for rapid API development.
Features
- Starlette Integration: Built on top of Starlette for high performance and ASGI compatibility
- Django-like Structure: Familiar project and app structure similar to Django
- ORM Integration: Built-in Tortoise ORM support with Aerich migrations
- Generic Views: Pre-built views for common CRUD operations
- Serializers: Django REST Framework-like serializers
- CLI Tools: Command-line interface for project management
- CORS Middleware: Built-in CORS support
- Manual Database Management: Safe, Django-like database migration workflow
Installation
Option 1: Install globally (recommended for CLI usage)
pip install rango-api
Option 2: Use manage.py (for project-specific usage)
# Clone or download the framework
# Use python manage.py commands instead of rango commands
Quick Start
Option A: Using global CLI (if installed globally)
# 1. Create a new project
rango startproject myproject
cd myproject
# 2. Create an app
rango startapp blog
# 3. Initialize database
rango initdb
# 4. Start server
rango runserver
Option B: Using manage.py (project-specific)
# 1. Create a new project
python manage.py startproject myproject
cd myproject
# 2. Create an app
python manage.py startapp blog
# 3. Initialize database
python manage.py initdb
# 4. Start server
python manage.py runserver
Database Management
Rango Framework uses Tortoise ORM with Aerich for database migrations, providing a Django-like experience.
Initial Setup (First Time Only)
# After creating a project and app
python manage.py initdb
Development Workflow
# 1. Modify models in your app
# ... edit models.py ...
# 2. Create migrations
python manage.py makemigrations "description of changes"
# 3. Apply migrations
python manage.py migrate
# 4. Check status (optional)
python manage.py migrate_status
Production Safety
- No automatic migrations: Database schema changes must be explicitly applied
- Manual migration control: You control when and how migrations are applied
- Automatic DB connection: Database connection is initialized on first request
- Migration tracking: Aerich tracks applied migrations
- Rollback support: Aerich supports migration rollbacks
For detailed database management guide, see DATABASE_GUIDE.md.
Tutorial
Create models with ForeignKey
from tortoise import fields, models
class Category(models.Model):
id = fields.IntField(pk=True)
name = fields.CharField(max_length=100)
class Product(models.Model):
id = fields.IntField(pk=True)
title = fields.CharField(max_length=255)
category = fields.ForeignKeyField('models.Category', related_name='products')
Serializers (nested FK supported)
from rango_api.serializers import ModelSerializer
from .models import Category, Product
class CategorySerializer(ModelSerializer):
class Meta:
model = Category
fields = ["id", "name"]
class ProductSerializer(ModelSerializer):
class Meta:
model = Product
fields = ["id", "title", "category"] # can send category or category_id
nested_serializers = {
'Category': CategorySerializer
}
Views (generic, with FK optimization)
from rango_api.generics import ListCreateView, RetrieveUpdateDeleteView
from .models import Product
from .serializers import ProductSerializer
class ProductListCreateView(ListCreateView):
model = Product
serializer_class = ProductSerializer
select_related = ['category'] # optimize FK
class ProductDetailView(RetrieveUpdateDeleteView):
model = Product
serializer_class = ProductSerializer
select_related = ['category']
URLs
from rango_api.router import Router
from .views import ProductListCreateView, ProductDetailView
router = Router()
router.add("/products", ProductListCreateView, methods=["GET", "POST"])
router.add("/products/{id}", ProductDetailView, methods=["GET", "PUT", "PATCH", "DELETE"])
Test the API
- Create category:
curl -X POST http://127.0.0.1:8000/categories \
-H "Content-Type: application/json" \
-d '{"name":"Electronics"}'
- Create product (supports category or category_id):
curl -X POST http://127.0.0.1:8000/products \
-H "Content-Type: application/json" \
-d '{"title":"Phone","category":1}'
Extensibility (DRF-like Hooks)
You can override hooks in generic views to customize behavior:
class ProductListCreateView(ListCreateView):
model = Product
serializer_class = ProductSerializer
def get_queryset(self, request):
return self.model.all().select_related('category')
async def before_create(self, request, data: dict) -> dict:
# mutate/validate incoming data
data.setdefault("title", data.get("title", "Untitled"))
return data
async def after_create(self, request, obj):
# side-effects, logging, etc.
return obj
class ProductDetailView(RetrieveUpdateDeleteView):
model = Product
serializer_class = ProductSerializer
async def before_update(self, request, obj, data: dict) -> dict:
# e.g. normalize FK input
if 'category' in data and 'category_id' not in data:
data['category_id'] = data.pop('category')
return data
Available hooks include: get_queryset, filter_queryset, before_create, perform_create, after_create, before_update, perform_update, after_update, before_delete, perform_delete, after_delete.
Project Structure
myproject/
├── apps/
│ └── blog/
│ ├── models.py
│ ├── serializers.py
│ ├── views.py
│ └── urls.py
├── project/
│ ├── settings.py
│ ├── urls.py
│ ├── views.py
│ └── asgi.py
├── main.py
└── manage.py
Basic Usage
Models
from tortoise import fields, models
class Post(models.Model):
title = fields.CharField(max_length=255)
content = fields.TextField()
created_at = fields.DatetimeField(auto_now_add=True)
Serializers
from rango_api.serializers import ModelSerializer
from .models import Post
class PostSerializer(ModelSerializer):
class Meta:
model = Post
fields = ["id", "title", "content", "created_at"]
Views
from rango_api.generics import ListCreateView, RetrieveUpdateDeleteView
from .models import Post
from .serializers import PostSerializer
class PostListCreateView(ListCreateView):
model = Post
serializer_class = PostSerializer
class PostDetailView(RetrieveUpdateDeleteView):
model = Post
serializer_class = PostSerializer
URLs
from rango_api.router import Router
from .views import PostListCreateView, PostDetailView
router = Router()
router.add("/posts", PostListCreateView, methods=["GET", "POST"])
router.add("/posts/{id}", PostDetailView, methods=["GET", "PUT", "DELETE"])
CLI Commands
Project Management
python manage.py startproject <name>- Create a new projectpython manage.py startapp <name>- Create a new apppython manage.py runserver [host] [port]- Start development server
Database Management
python manage.py initdb- Initialize database and Aerich config (first time only)python manage.py makemigrations [message]- Create database migrationspython manage.py migrate- Apply database migrationspython manage.py migrate_status- Show migration status
Alternative CLI (if installed globally)
rango startproject <name>- Create a new projectrango startapp <name>- Create a new apprango initdb- Initialize databaserango makemigrations [message]- Create migrationsrango migrate- Apply migrationsrango migrate_status- Show migration statusrango runserver [host] [port]- Start development server
Requirements
- Python 3.8+
- Starlette
- Tortoise ORM
- Aerich (for migrations)
- Uvicorn
License
This project is licensed under the MIT License - see the LICENSE file for details.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Support
If you have any questions or need help, please open an issue on GitHub.
Metadata
Release files for rango-api 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| rango_api-0.1.1.tar.gz | 21.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| rango_api-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 39.5 kB
Release files / rango_api-0.1.1.tar.gz
| Download URL | rango_api-0.1.1.tar.gz |
|---|---|
| Size | 21.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
941ae35f56d4e9d9dd9ffaf8a20443c6fe1156718ffb03e96f54d9b4c5581f55
|
|
BLAKE2b-256 checksum How to use checksums |
5264f06c32b67caf6b490d5e02efad0c982c44b9352ee40ed4ef74dfd063a68b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.5
|
Release files / rango_api-0.1.1-py3-none-any.whl
| Download URL | rango_api-0.1.1-py3-none-any.whl |
|---|---|
| Size | 18.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b7842299aaf25b52b6b3c0e26ae375eab54f738ed204443a05e2739eec35c944
|
|
BLAKE2b-256 checksum How to use checksums |
ab27b649708f769556f3b4cb4bf366afe49aa531123e05aac38155161c2d33bf
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.5
|