Skip to main content

A Django library for standardized API responses.

Project description

Django Unified Response

A reusable Django app that provides standardized, consistent, and customizable JSON responses for your Django REST Framework APIs.

Features

  • Unified Success Response: All successful responses are wrapped in a consistent {"status": "success", "data": ...} structure.
  • Unified Error Response: All exceptions (validation, authentication, custom errors, etc.) are caught and returned in a consistent {"status": "error", "message": ..., "error_code": ...} structure.
  • Custom Exceptions: Ships with a set of clear, high-level exceptions (NotFoundException, IntegrityException, etc.) for common API scenarios.
  • Pluggable & Customizable: Don't like the default format? You can provide your own formatter class to define a project-wide custom response structure.
  • Metadata Support: Easily pass extra metadata (e.g., pagination, request IDs) in your responses via a meta key.

Installation

Install the package from PyPI:

pip install django-unified-response

Or, if you are developing locally, navigate to the project root and install in editable mode:

pip install -e .

Quick Start & Configuration

  1. Ensure rest_framework is in your INSTALLED_APPS in settings.py. You do not need to add django_unified_response to INSTALLED_APPS as it doesn't contain any models or template tags.

  2. Configure Django REST Framework in your settings.py to use the custom exception handler and renderer.

    # settings.py
    
    REST_FRAMEWORK = {
        'DEFAULT_RENDERER_CLASSES': [
            'django_unified_response.renderers.UnifiedJSONRenderer',
            # Add BrowsableAPIRenderer if you want to use the DRF web interface for testing
            'rest_framework.renderers.BrowsableAPIRenderer',
        ],
        'EXCEPTION_HANDLER': 'django_unified_response.handlers.custom_exception_handler',
    }
    

How to Use

Success Responses

Your views will now automatically return formatted success responses. You just need to return a standard DRF Response object.

# in your views.py
from rest_framework.views import APIView
from rest_framework.response import Response

class MyView(APIView):
    def get(self, request):
        payload = {"id": 1, "name": "Test Item"}
        return Response(payload)

The client will receive:

{
    "status": "success",
    "message": "Success",
    "data": {
        "id": 1,
        "name": "Test Item"
    },
    "meta": {}
}

To include metadata, add a meta key to your response dictionary. The renderer will automatically separate it.

# in your views.py
def get(self, request):
    payload = {
        "items": [{"id": 1}, {"id": 2}],
        "meta": {"pagination": {"count": 2, "page": 1}}
    }
    return Response(payload)

Error Responses

Using Standard DRF Exceptions

The library will automatically catch and format default DRF exceptions. For example, using a serializer:

# in your views.py
def post(self, request):
    serializer = MySerializer(data=request.data)
    # This will raise a DRF ValidationError, which our handler will format
    serializer.is_valid(raise_exception=True)
    return Response(serializer.data, status=201)

The client will receive a formatted validation_error:

{
    "status": "error",
    "message": "Input validation failed.",
    "error_code": "validation_error",
    "errors": {
        "email": [ "Enter a valid email address." ]
    },
    "meta": {}
}

Using Custom Library Exceptions

For more specific business logic errors, import and raise the custom exceptions from the library.

# in your views.py
from django_unified_response.exceptions import NotFoundException, IntegrityException
from django.db import IntegrityError
from my_app.models import Product

def get_product(request, pk):
    try:
        product = Product.objects.get(pk=pk)
    except Product.DoesNotExist:
        raise NotFoundException() # Returns a formatted 404

def create_product(request):
    try:
        # ... logic to create product ...
    except IntegrityError:
        # Returns a formatted 409 Conflict
        raise IntegrityException("A product with this SKU already exists.")

Advanced Customization

If the default response structure doesn't fit your needs, you can define your own global response format. The library is designed to be flexible, just like Django itself.

  1. Create a new formatter class anywhere in your Django project. It should inherit from django_unified_response.formatters.DefaultResponseFormatter. You only need to override the methods you want to change.

    For example, if you only want to change the error format but keep the success format the same, you can do this:

    # my_app/formatters.py
    from django_unified_response.formatters import DefaultResponseFormatter
    
    class CustomResponseFormatter(DefaultResponseFormatter):
        # The format_success method is inherited and works as before.
        # We only override format_error.
        def format_error(self, message, error_code, errors=None, status_code=400, meta=None):
            return {
                "ok": False,
                "error": {
                    "code": error_code,
                    "message": message,
                    "details": errors
                },
                "meta": meta or {}
            }
    
  2. Update your settings.py to point to your new class:

    # settings.py
    
    # Point to your custom formatter class
    UNIFIED_RESPONSE_FORMATTER_CLASS = 'my_app.formatters.CustomResponseFormatter'
    

That's it! Your project will now use your custom error format while still using the library's default success format.

Contributing

Contributions are welcome! If you have a feature request, bug report, or want to improve the library, please follow these steps:

  1. Fork the repository on GitHub.
  2. Create a new branch for your feature or bug fix.
  3. Make your changes and add tests to cover them.
  4. Ensure all tests pass by running them from the test_project directory.
  5. Submit a pull request with a clear description of your changes.

License

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

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

django_unified_response-0.1.0.tar.gz (10.2 kB view details)

Uploaded Source

Built Distribution

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

django_unified_response-0.1.0-py3-none-any.whl (8.0 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: django_unified_response-0.1.0.tar.gz
  • Upload date:
  • Size: 10.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.7

File hashes

Hashes for django_unified_response-0.1.0.tar.gz
Algorithm Hash digest
SHA256 d59250fc9a08a8460a75b4c1dbab170b7a2e9686b40c3d16f7477bbef123ffcc
MD5 5889f74c2788c831345fbc5a09adad84
BLAKE2b-256 5c9c821b3013e59c9ddad4f870a51a73eb3dc2d513f0605c32532ce3d34dcf17

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for django_unified_response-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 172f5d6b123a4a02047e82cdc97ab049b0f6f608d54f6f923e0e0cfce17d7d63
MD5 948d2700c7510fd47940f00d4941fd53
BLAKE2b-256 9643a51c9ee90bb06b5c9cbbdee813e741a5c820168d5c940b9d8eaa69a2d2fa

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