Skip to main content

A modern Python web framework built on Starlette with Django-like features and structure

Project description

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 project
  • python manage.py startapp <name> - Create a new app
  • python 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 migrations
  • python manage.py migrate - Apply database migrations
  • python manage.py migrate_status - Show migration status

Alternative CLI (if installed globally)

  • rango startproject <name> - Create a new project
  • rango startapp <name> - Create a new app
  • rango initdb - Initialize database
  • rango makemigrations [message] - Create migrations
  • rango migrate - Apply migrations
  • rango migrate_status - Show migration status
  • rango 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.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

rango_api-0.1.1.tar.gz (21.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

rango_api-0.1.1-py3-none-any.whl (18.5 kB view details)

Uploaded Python 3

File details

Details for the file rango_api-0.1.1.tar.gz.

File metadata

  • Download URL: rango_api-0.1.1.tar.gz
  • Upload date:
  • Size: 21.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for rango_api-0.1.1.tar.gz
Algorithm Hash digest
SHA256 941ae35f56d4e9d9dd9ffaf8a20443c6fe1156718ffb03e96f54d9b4c5581f55
MD5 a80728c9c7324207faace81d303cee6a
BLAKE2b-256 5264f06c32b67caf6b490d5e02efad0c982c44b9352ee40ed4ef74dfd063a68b

See more details on using hashes here.

File details

Details for the file rango_api-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: rango_api-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 18.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for rango_api-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 b7842299aaf25b52b6b3c0e26ae375eab54f738ed204443a05e2739eec35c944
MD5 66af32717e6900de4d92af45693caaf7
BLAKE2b-256 ab27b649708f769556f3b4cb4bf366afe49aa531123e05aac38155161c2d33bf

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page