Metadata-Version: 2.4
Name: rango-api
Version: 0.1.1
Summary: A modern Python web framework built on Starlette with Django-like features and structure
Home-page: https://github.com/reshadMajumder/rango
Author: Jahidul Hassan Reshad
Author-email: Jahidul Hassan Reshad <hassanjahidul365@gmail.com>
License: MIT License
        
        Copyright (c) 2025 Jahidul Hassan Reshad
        
        
        Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
        
        
Project-URL: Homepage, https://github.com/reshadMajumder/rango
Project-URL: Documentation, https://github.com/reshadMajumder/rango#readme
Project-URL: Repository, https://github.com/reshadMajumder/rango
Project-URL: Issues, https://github.com/reshadMajumder/rango
Keywords: web,framework,Starlette,api,django-like
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: aerich==0.9.2
Requires-Dist: aiosqlite==0.21.0
Requires-Dist: annotated-types==0.7.0
Requires-Dist: anyio==4.11.0
Requires-Dist: asyncclick==8.3.0.7
Requires-Dist: click==8.3.0
Requires-Dist: colorama==0.4.6
Requires-Dist: dictdiffer==0.9.0
Requires-Dist: h11==0.16.0
Requires-Dist: idna==3.10
Requires-Dist: iso8601==2.1.0
Requires-Dist: markdown-it-py==4.0.0
Requires-Dist: mdurl==0.1.2
Requires-Dist: pydantic==2.12.0
Requires-Dist: pydantic_core==2.41.1
Requires-Dist: Pygments==2.19.2
Requires-Dist: pypika-tortoise==0.6.2
Requires-Dist: pytz==2025.2
Requires-Dist: rich==14.2.0
Requires-Dist: shellingham==1.5.4
Requires-Dist: sniffio==1.3.1
Requires-Dist: starlette==0.48.0
Requires-Dist: tortoise-orm==0.25.1
Requires-Dist: typer==0.19.2
Requires-Dist: typing-inspection==0.4.2
Requires-Dist: typing_extensions==4.15.0
Requires-Dist: uvicorn==0.37.0
Provides-Extra: dev
Requires-Dist: pytest>=6.0; extra == "dev"
Requires-Dist: pytest-asyncio; extra == "dev"
Requires-Dist: black; extra == "dev"
Requires-Dist: flake8; extra == "dev"
Requires-Dist: mypy; extra == "dev"
Dynamic: author
Dynamic: home-page
Dynamic: license-file
Dynamic: requires-python

# 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)
```bash
pip install rango-api
```

### Option 2: Use manage.py (for project-specific usage)
```bash
# Clone or download the framework
# Use python manage.py commands instead of rango commands
```

## Quick Start

### Option A: Using global CLI (if installed globally)

```bash
# 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)

```bash
# 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)

```bash
# After creating a project and app
python manage.py initdb
```

### Development Workflow

```bash
# 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](DATABASE_GUIDE.md).

## Tutorial

### Create models with ForeignKey

```python
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)

```python
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)

```python
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

```python
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:
```bash
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):
```bash
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:

```python
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

```python
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

```python
from rango_api.serializers import ModelSerializer
from .models import Post

class PostSerializer(ModelSerializer):
    class Meta:
        model = Post
        fields = ["id", "title", "content", "created_at"]
```

### Views

```python
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

```python
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](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.
