Skip to main content

Django REST Framework-inspired ViewSets and utilities for FastAPI

This project has been archived.

The maintainers of this project have marked this project as archived. No new releases are expected.

Project description

FastAPI Mason

Python FastAPI MIT License

Django REST Framework-inspired ViewSets and utilities for FastAPI applications.

Features

  • ViewSets: Django-like ViewSets with automatic CRUD operations
  • Decorators: Simple registration of ViewSets and custom actions
  • Permissions: Built-in permission system with customizable access control
  • Pagination: Multiple pagination strategies (Limit/Offset, Page Number, Cursor)
  • Response Wrappers: Consistent API response formatting
  • State Management: Request-scoped state management
  • Type Safety: Full type hints and generic support

Installation

pip install fastapi-mason

Quick Start

1. Define your model and schemas

from tortoise.models import Model
from tortoise import fields
from tortoise.contrib.pydantic import pydantic_model_creator

class Company(Model):
    id = fields.IntField(pk=True)
    name = fields.CharField(max_length=100)
    description = fields.TextField()
    
    class Meta:
        table = "companies"

# Generate schemas
CompanySchema = pydantic_model_creator(Company, name="CompanySchema")
CompanyCreateSchema = pydantic_model_creator(Company, name="CompanyCreateSchema", exclude_readonly=True)

2. Create a ViewSet

from fastapi import APIRouter
from fastapi_mason import decorators
from fastapi_mason.viewsets import ModelViewSet
from fastapi_mason.permissions import IsAuthenticated

router = APIRouter(prefix="/companies", tags=["companies"])

@decorators.viewset(router)
class CompanyViewSet(ModelViewSet[Company]):
    model = Company
    read_schema = CompanySchema
    create_schema = CompanyCreateSchema
    
    # Optional: Add permissions
    permission_classes = [IsAuthenticated]
    
    def get_queryset(self):
        return Company.all()
    
    @decorators.action()
    async def stats(self):
        total = await Company.all().count()
        return {"total_companies": total}

3. Include in your FastAPI app

from fastapi import FastAPI

app = FastAPI()
app.include_router(router)

This automatically creates the following endpoints:

  • GET /companies/ - List companies
  • POST /companies/ - Create company
  • GET /companies/{id}/ - Get specific company
  • PUT /companies/{id}/ - Update company
  • DELETE /companies/{id}/ - Delete company
  • GET /companies/stats/ - Custom action

Core Components

ViewSets

ModelViewSet

Provides full CRUD operations (Create, Read, Update, Delete):

from fastapi_mason.viewsets import ModelViewSet

class CompanyViewSet(ModelViewSet[Company]):
    model = Company
    read_schema = CompanySchema
    create_schema = CompanyCreateSchema

ReadOnlyViewSet

Provides only read operations (List, Retrieve):

from fastapi_mason.viewsets import ReadOnlyViewSet

class CompanyViewSet(ReadOnlyViewSet[Company]):
    model = Company
    read_schema = CompanySchema

Permissions

Built-in permission classes:

from fastapi_mason.permissions import IsAuthenticated, IsAuthenticatedOrReadOnly

class CompanyViewSet(ModelViewSet[Company]):
    permission_classes = [IsAuthenticated]
    
    def get_permissions(self):
        if self.action == "list":
            return []  # Allow anonymous access to list
        return [IsAuthenticated()]

Pagination

Multiple pagination strategies available:

from fastapi_mason.pagination import PageNumberPagination, LimitOffsetPagination, CursorPagination

class CompanyViewSet(ModelViewSet[Company]):
    pagination = PageNumberPagination  # Default: 10 items per page
    
    # Or disable pagination
    # pagination = DisabledPagination

Custom Actions

Add custom endpoints with the @action decorator:

@decorators.action(methods=["POST"], detail=True)
async def activate(self, item_id: int):
    company = await self.get_object(item_id)
    company.is_active = True
    await company.save()
    return {"message": "Company activated"}

@decorators.action(methods=["get"], detail=False, response_model=dict)
async def statistics(self):
    return {
        "total": await Company.all().count(),
        "active": await Company.filter(is_active=True).count()
    }

Advanced Usage

Custom Permissions

from fastapi_mason.permissions import BasePermission

class IsOwnerOrReadOnly(BasePermission):
    async def has_object_permission(self, request, view, obj):
        if request.method in ("GET", "HEAD", "OPTIONS"):
            return True
        return obj.owner_id == view.user.id

Response Wrappers

Customize response format:

from fastapi_mason.wrappers import ResponseWrapper

class CustomResponseWrapper(ResponseWrapper):
    def wrap(self, data, **kwargs):
        return {
            "success": True,
            "data": data,
            "timestamp": datetime.now().isoformat()
        }

class CompanyViewSet(ModelViewSet[Company]):
    single_wrapper = CustomResponseWrapper
    list_wrapper = CustomResponseWrapper

State Management

Access request state in your ViewSet:

async def auth_dependency():
    user = {'id': 1, 'name': 'John Doe'}  # Your logic for get user
    BaseStateManager.set_user(user)


router = APIRouter(prefix='/companies', dependencies=[Depends(auth_dependency)])

@decorators.viewset(router)
class CompanyViewSet(ModelViewSet[Company]):
    def get_queryset(self):
        if self.state.user:
            return Company.filter(owner=self.state.user)
        return Company.filter(is_public=True)

Examples

Check the /app directory for complete examples:

Requirements

  • Python 3.12+
  • FastAPI 0.115.13+
  • Tortoise ORM 0.25.1+

License

This project is licensed under the MIT License - see the LICENSE file for details.

Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'fix(generics): Feature message')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Roadmap

  • Enhanced filtering and searching
  • Advanced serialization options
  • More built-in permission classes
  • Comprehensive documentation site
  • Performance optimizations

Support

If you encounter any issues or have questions, 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

fastapi_mason-0.1.0.tar.gz (53.7 kB view details)

Uploaded Source

Built Distribution

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

fastapi_mason-0.1.0-py3-none-any.whl (20.4 kB view details)

Uploaded Python 3

File details

Details for the file fastapi_mason-0.1.0.tar.gz.

File metadata

  • Download URL: fastapi_mason-0.1.0.tar.gz
  • Upload date:
  • Size: 53.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.4.27

File hashes

Hashes for fastapi_mason-0.1.0.tar.gz
Algorithm Hash digest
SHA256 44c2da6c32e12c24012a0c8fd5341cc86b0b06a51ffeb178947c9fabccdbd1f9
MD5 b0baf787b76d34b2887ea74c8e467332
BLAKE2b-256 a9a74a18029e2f0240cd32a511ceb8d0a71c44074a272137b4824b68a0b24709

See more details on using hashes here.

File details

Details for the file fastapi_mason-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for fastapi_mason-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 bfd5211511dc5b4d169f80729b3989ecdad4b06813b79aff98c1dc9a31e3eb90
MD5 1dc619f3ab7c89b2084a526c62aa1b8d
BLAKE2b-256 1b7a5c6d7a537eb48bd03e1300ec0873a4da527a09d682d85be36c1922d69cc9

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