A modern Python web framework built on FastAPI with Django-like features and structure
Project description
Rango API Framework
A modern Python web framework built on FastAPI with Django-like features for rapid API development.
Features
- FastAPI Integration: Built on top of FastAPI for high performance and automatic API documentation
- Django-like Structure: Familiar project and app structure similar to Django
- ORM Integration: Built-in Tortoise ORM support with 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
Installation
pip install rango-api
Quick Start
1. Create a new project
rango startproject myproject
cd myproject
2. Create an app
rango startapp blog
Initialize database
Init Aerich config
aerich init -t project.settings.TORTOISE_ORM
Create database & initial migration
aerich init-db
Make migrations after changing models
aerich migrate --name "initial"
aerich upgrade
Every time you create or modify models: aerich migrate --name "your_message" → aerich upgrade
3. Run migrations
rango makemigrations
rango migrate
4. Start the development server
rango runserver
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
rango startproject <name>- Create a new projectrango startapp <name>- Create a new apprango makemigrations [message]- Create database migrationsrango migrate- Apply database migrationsrango runserver [host] [port]- Start development server
Requirements
- Python 3.8+
- FastAPI
- Tortoise ORM
- 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.
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 rango_api-0.1.0.tar.gz.
File metadata
- Download URL: rango_api-0.1.0.tar.gz
- Upload date:
- Size: 18.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
510d17c9581e4cc1e235bafd6ef32f1e858bd6ce24ce4b8f1a456c2434b6cb58
|
|
| MD5 |
58bd68e51c9408503a2dbef475985694
|
|
| BLAKE2b-256 |
3145d70a56b6f4eeab19b8c1b6523d36f08517f072516bae684504582e524354
|
File details
Details for the file rango_api-0.1.0-py3-none-any.whl.
File metadata
- Download URL: rango_api-0.1.0-py3-none-any.whl
- Upload date:
- Size: 17.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
436e5b6bb83d613728c5dcc08f6f2f16094f8ab0e0776303f8f1b8d76b4d6b49
|
|
| MD5 |
944dec4173625e089e5c95dafd96a5a7
|
|
| BLAKE2b-256 |
b7b9bae5c5f9f2726ac62082f1064f457bc607e19b127fdbdb1336a7b263f36d
|