Metadata-Version: 2.4
Name: sanic-restful-framework
Version: 0.0.2
Summary: An extensible, high-performance web framework based on Sanic, designed to bring the best parts of Django REST Framework into the world of asynchronous programming. Ideal for building fast, scalable APIs with minimal setup.
Author-email: Chacer <1364707405c@gmail.com>
License: MIT
Project-URL: Homepage, https://github.com/bitblames/sanic-restful-framework
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: aiohttp<4,>=3.13
Requires-Dist: bcrypt>=4.1.2
Requires-Dist: packaging<27,>=26
Requires-Dist: pydantic<3,>=2.6.1
Requires-Dist: pydantic_core<3,>=2.41
Requires-Dist: PyJWT<3,>=2.10
Requires-Dist: redis<8,>=7.1
Requires-Dist: sanic<26,>=25.0.0
Requires-Dist: sanic_jwt<2,>=1.8.0
Requires-Dist: tortoise-orm==0.25.1
Provides-Extra: dev
Requires-Dist: pytest<10,>=9.0; extra == "dev"
Requires-Dist: pytest-asyncio<2,>=1.3; extra == "dev"
Requires-Dist: black; extra == "dev"
Requires-Dist: isort; extra == "dev"
Requires-Dist: ruff; extra == "dev"
Requires-Dist: build; extra == "dev"
Dynamic: license-file

#  Sanic RESTful Framework (SRF)

A RESTful API framework based on [Sanic](https://sanic.dev/), providing a Django REST Framework-like development experience to help you quickly build high-performance Web APIs.

- **GitHub**: https://github.com/bitblames/sanic-restful-framework
- **PyPI**: https://pypi.org/project/sanic-restful-framework/
- **Documentation**: https://sanic-restful-framework.bitflames.com/

## Features

- 🚀 **Base ViewSets** - Complete CRUD operations (Create, Retrieve, Update, Destroy, List).
- 🔒 **Pydantic Integration** - Data validation and serialization using Pydantic.
- 🔍 **Powerful Filtering System** - Support for search, JSON logic filtering, query parameter filtering, and ordering.
- 📄 **Pagination** - Built-in pagination handler with customizable pagination parameters.
- 🛡️ **Authentication & Permissions** - JWT-based authentication system with permission control, and provides third-party authentication integration, such as GitHub login.
- ⚡ **Asynchronous ORM** - Built-in support for asynchronous database queries using Tortoise ORM, and more.
- 💓 **Health Checks** - Built-in health check routes supporting multiple service checks.
- 🎯 **Auto Route Registration** - Intelligent route registration with support for custom actions.
- 🔄 **Rate Limiting** - Built-in rate limiting middleware to control request rates.

## Requirements

- Python >= 3.11
- Sanic >= 25.0.0
- Tortoise ORM >= 0.20.0
- Pydantic >= 2.6.0

## Installation

### Install from Source

```bash
# Recommended installation method
pip install sanic-restful-framework

# Install production dependencies
pip install -e .

# Install development dependencies
pip install -e ".[dev]"
```

## Quick Start

To get started with SRF, follow these steps:

1. **Define your models** using Tortoise ORM. Create your database models that inherit from `tortoise.models.Model` and define the necessary fields.

2. **Create Pydantic schemas** for data validation and serialization. Define separate schemas for reading (output) and writing (input) operations.

3. **Create a ViewSet** by inheriting from `BaseViewSet`. Configure the model, search fields, and filter fields. Implement the `queryset` property to return your model's queryset, and optionally override `get_schema()` to return different schemas based on the request method.

4. **Register routes** using `SanicRouter`. Create a router instance with an optional prefix, register your ViewSet with a path, and add the router's blueprint to your Sanic application.

5. **Run your application** using Sanic's built-in server or your preferred ASGI server.

## Core Features

### ViewSets

`BaseViewSet` provides standard CRUD operations:

- `list()` - GET /resource/ - Retrieve a list of resources
- `create()` - POST /resource/ - Create a new resource
- `retrieve()` - GET /resource/<id>/ - Retrieve a single resource
- `update()` - PUT/PATCH /resource/<id>/ - Update a resource
- `destroy()` - DELETE /resource/<id>/ - Delete a resource

```python
from srf.views import BaseViewSet
from tortoise.queryset import QuerySet
from .models import Project
from .schema import ProjectSchemaReader

class ProjectViewSet(BaseViewSet):
    def get_schema(self, request, *args, is_safe=False, **kwargs):
        return ProjectSchemaReader

    @property
    def queryset(self) -> QuerySet:
        return Project.all()
```

Congrats! At this point, you have completed a basic CRUD (Create, Read, Update, Delete) interface, just like in Django REST Framework.

### Custom Actions

Use the `@action` decorator to define custom actions:

```python
from srf.views import action
from sanic.response import JSONResponse

class ProjectViewSet(BaseViewSet):
    @action(detail=False, url_path="featured", methods=["get"])
    async def list_featured(self, request):
        projects = await self.queryset.filter(is_featured=True)
        schema = self._get_schema(request, is_safe=True)
        data = [schema.model_validate(p).model_dump(by_alias=True) for p in await projects]
        return JSONResponse(data)

    @action(detail=True, url_path="archive", methods=["post"])
    async def archive(self, request, pk):
        project = await self.get_object(request, pk)
        project.is_archived = True
        await project.save()
        return JSONResponse({"status": "archived"})
```

### Filters

The framework includes multiple built-in filters:

#### 1. Search Filter (SearchFilter)

```python
# GET /projects/?search=api
# Searches for "api" in fields specified by search_fields
```

#### 2. JSON Logic Filter (JsonLogicFilter)

```python
# GET /projects/?filter={"and":[{"==":[{"var":"is_active"},true]},{"like":[{"var":"name"},"api"]}]}
```

#### 3. Query Parameter Filter (QueryParamFilter)

```python
# GET /projects/?name=myproject&is_active=true
```

#### 4. Ordering Filter (OrderingFactory)

```python
# GET /projects/?sort=name,-created_date
# Orders by name ascending, created_date descending
```

### Pagination

Pagination automatically reads `page` and `page_size` from query parameters:

```python
# GET /projects/?page=1&page_size=20
```

Response format:

```json
{
  "count": 100,
  "next": true,
  "previous": false,
  "results": [...]
}
```

### Authentication & Permissions

#### Authentication Middleware

The framework provides JWT authentication middleware:

```python
from srf.middleware.authmiddleware import set_user_to_request_ctx

app.middleware("request")(set_user_to_request_ctx)
```

#### Permission Classes

```python
from srf.permission.permission import IsAuthenticated, IsRoleAdminUser, IsSafeMethodOnly

class ProjectViewSet(BaseViewSet):
    permission_classes = (IsAuthenticated,)  # Requires authentication
    # or
    permission_classes = (IsRoleAdminUser,)  # Requires admin role
    # or read-only: allow GET/HEAD/OPTIONS only
    permission_classes = (IsSafeMethodOnly,)
```

### Health Checks

The framework provides health check routes:

```python
from srf.health.route import bp as health_bp

app.blueprint(health_bp)
```

Access `GET /health/` to check the status of various services. Register check classes (e.g. `RedisCheck`, `SQLiteCheck`) and attach dependencies (e.g. `app.ctx.redis`, `app.ctx.sqlite`) so the health blueprint can instantiate them.

## Configuration

SRF reads configuration from `srf.config.settings` (e.g. `SECRET_KEY`, `NON_AUTH_ENDPOINTS`, `DEFAULT_FILTERS`). You can override via Sanic `app.config` after calling `srf.config.srfconfig.set_app(app)` (or by passing config when creating the app).

```python
from srf.config.settings import DEFAULT_FILTERS

app.config.JWT_SECRET = "your-secret-key"
app.config.NON_AUTH_ENDPOINTS = ("register", "login", "send-verification-email", "health", "callback", "login_by_code")
app.config.DEFAULT_FILTERS = DEFAULT_FILTERS
```

For auth email verification and social login, ensure `app.config.FORMATTER` (or equivalent) provides `EMAIL_CODE_REDIS` and `SOCIAL_LOGIN_REDIS_EX_CODE` key prefixes, and that `app.ctx.redis` is set.

## Dependencies

Main dependencies:

- `sanic>=25.0.0` - Async web framework
- `pydantic>=2.6.1` - Data validation
- `tortoise-orm>=0.25.1` - ORM
- `sanic-jwt>=1.8.0` - JWT authentication

See `pyproject.toml` for the complete dependency list.

## Development

### Install Development Dependencies

```bash
pip install -e ".[dev]"
```

## License

MIT License

## Author

| Name   | Email                 |
| ------ | --------------------- |
| Chacer | 1364707405c@gmail.com |

## Contributing

Issues and Pull Requests are welcome!

## Want to join? Email us!
