Skip to content

Latest commit

 

History

History
158 lines (113 loc) · 4.08 KB

README.md

File metadata and controls

158 lines (113 loc) · 4.08 KB

No Boilerplate, just rapid Django API ⚡️

Write powerful Django APIs with minimal code. Djapy combines Django's robustness with modern API development practices, giving you a clean, intuitive way to build REST APIs.

PyPI version Python Versions Django Versions Downloads

@djapify
def get_user(request, user_id: int) -> UserSchema:
   return User.objects.get(id=user_id)

✨ Why Djapy?

from djapy import djapify, Schema


class UserOut(BaseModel):
   id: int
   username: str
   is_active: bool


@djapify
def get_users(request) -> list[UserOut]:
   return User.objects.filter(is_active=True)

Write Django REST APIs in pure Python. No serializers, no viewsets, no boilerplate, no external url routers - just clean, typed, and maintainable code.

🚀 Key Features

  • Zero Boilerplate: Build APIs with pure Python and Django
  • Type Safety: Full Python type hints support
  • Modern Validation: Built-in Pydantic integration
  • Hyperfast Performance: Optimized for speed
  • Django Compatible: Works with any Django project
  • OpenAPI Support: Automatic Swagger documentation
  • IDE Friendly: Full intellisense, endpoints (PyCharm) and type support

🎯 Quick Start

  1. Install Djapy
pip install djapy
  1. Create Your First API
from djapy import djapify, Schema
from django.contrib.auth.models import User


class UserSchema(Schema):
   id: int
   username: str
   email: str


@djapify
def list_users(request) -> list[UserSchema]:
   return User.objects.all()


@djapify
def get_user(request, user_id: int) -> {200: UserSchema, 404: str}:
   try:
      return User.objects.get(id=user_id)
   except User.DoesNotExist:
      return "User not found", 404
  1. Add to URLs
from django.urls import path

urlpatterns = [
   path('users/', list_users),
   path('users/<int:user_id>/', get_user),
]

🔥 Core Features

1. Native Type System

from typing import Optional
from djapy import djapify, Schema
from djapy.pagination import paginate


class UserFilter(Schema):
   search: Optional[str]
   is_active: bool = True


@djapify
@paginate
def search_users(request, filters: UserFilter) -> list[Schema]:
   queryset = User.objects.filter(is_active=filters.is_active)
   if filters.search:
      queryset = queryset.filter(username__icontains=filters.search)
   return queryset

2. Smart Request Handling

@djapify
def create_user(request, data: UserCreate, team_id: int) -> {201: UserSchema}:
   # Automatic validation and parsing
   return 201, User.objects.create(**data.dict())

Learn more about type system and requests, here.

3. Error Handling

@djapify
def make_payment(request, amount: float) -> {200: PaymentSchema}:
   if request.user.balance < amount:
      raise MessageException("Insufficient balance")
   return Payment.objects.create(user=request.user, amount=amount)

More about error handling, here.

🔄 Migration from DRF

DRF Concept Djapy Equivalent
ViewSets Function-based views with @djapify
Serializers Pydantic models
Permissions Python decorators
Filters Query parameters
Pagination Built-in pagination helpers

📚 Documentation

Visit djapy.io for comprehensive documentation.

🤝 Community & Support