Skip to main content

A library for Django Rest Framework returning consistent and easy-to-parse API error messages.

Project description

Django Rest Framework Simple API Errors

PyPI test workflow codecov pyversions

What is this?

A library for Django Rest Framework returning consistent, predictable and easy-to-parse API error messages.

This library was built with RFC7807 guidelines in mind, but with a small twist: it defines a "problem detail" as a list, but it still serves as a way to include errors in a predictable and easy-to-parse format for any API consumer. Error messages are formatted using RFC7807 keywords and DRF exception data.

Compared to other similar and popular libraries, this library is based on RFC7807 guidelines and aims to provide not only a standardized format for error details, but also human readability.

Table of Contents

Installation

Install using the command line:

pip install drf-simple-api-errors

Usage

Exception Handler

Add EXCEPTION_HANDLER in your REST_FRAMEWORK settings of your Django project settings file:

REST_FRAMEWORK = {
    # ...
    "EXCEPTION_HANDLER": "drf_simple_api_errors.exception_handler",
}

Error structure overview

API error messages typically include the following keys:

  • "title" (str): A brief summary that describes the problem type
  • "detail" (list[str] | None): A list of specific explanations related to the problem
  • "invalid_params" (list[dict] | None): A list of dict containing details about parameters that were invalid or malformed in the request. Each dict within this list provides:
    • "name" (str): The name of the parameter that was found to be invalid
    • "reasons" (list[str]): A list of strings describing the specific reasons why the parameter was considered invalid or malformed
{
    "title": "Error message.",
    "detail": [
        "error",
        ...
    ],
    "invalid_params": [
        {
            "name": "field_name",
            "reason": [
                "error",
                ...
            ]
        },
        ...
    ]
}

Example JSON Error Responses

Field validation errors

{
    "title": "Error message.",
    "invalid_params": [
        {
            "name": "field_name",
            "reason": [
                "error",
                ...
            ]
        },
        ...
    ]
}

Non-fields validation errors

{
  "title": "Error message.",
  "detail": [
    "error",
    ...
  ]
}

Other bad requests with no detail

{
  "title": "Error message."
}

Settings

Default available settings:

DRF_SIMPLE_API_ERRORS = {
    "CAMELIZE": False,
    "EXTRA_HANDLERS": [],
    "FIELDS_SEPARATOR": ".",
}
  • CAMELIZE

Camel case support for Django Rest Framework exceptions JSON error responses.

If CAMELIZE is set to True:

{
  "title": "Error message.",
  "invalidParams": [
    {
      "name": "fieldName",
      "reason": [
        "error",
        ...
      ]
    }
    ...
  ]
}
  • EXTRA_HANDLERS

Support for exceptions that differ from the standard structure of the Django Rest Framework.

For instance, you may want to specify you own exception:

class AuthenticationFailed(exceptions.AuthenticationFailed):
    def __init__(self, detail=None, code=None):
        """
        Builds a detail dictionary for the error to give more information
        to API users.
        """
        detail_dict = {"detail": self.default_detail, "code": self.default_code}

        if isinstance(detail, dict):
            detail_dict.update(detail)
        elif detail is not None:
            detail_dict["detail"] = detail

        if code is not None:
            detail_dict["code"] = code

        super().__init__(detail_dict)

Use exception in code:

def my_func():
    raise AuthenticationFailed(
        {
            "detail": _("Error message."),
            "messages": [
                {
                    "metadata": "metadata_data",
                    "type": "type_name",
                    "message": "error message",
                }
            ],
        }
    )

This will result in:

AuthenticationFailed(
    {
        "detail": "Error message.",
        "messages": [
            {
                "metadata": "metadata_data",
                "type": "type_name",
                "message": "error message",
            }
        ],
    }
)

You can handle this by creating a handlers.py file and specifying an handler for your use case:

def handle_exc_custom_authentication_failed(exc):
    from path.to.my.exceptions import AuthenticationFailed

    if isinstance(exc, AuthenticationFailed):
        try:
            exc.detail = exc.detail["messages"][0]["message"]
        except (KeyError, IndexError):
            exc.detail = exc.detail["detail"]

    return exc

Then add it to the EXTRA_HANDLERS list in this package settings:

DRF_SIMPLE_API_ERRORS = {
    "EXTRA_HANDLERS": [
        "path.to.my.handlers.handle_exc_custom_authentication_failed",
        # ...
    ]
}
  • FIELDS_SEPARATOR

Support for nested dicts containing multiple fields to be flattened.

If FIELDS_SEPARATOR is set to .:

{
    "field1": {
        "field2": "value"
    }
}

Will result in:

{
    "field1.field2": "value"
}

Testing

All the necessary commands are included in the Makefile.

We are using tox and poetry to run tests in every supported Python version.

Run test with the commands below:

make install
make test

Support

Please open an issue.

Contributing

Please use the Github Flow. In a nutshell, create a branch, commit your code, and open a pull request.

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

drf_simple_api_errors-1.0.2.tar.gz (6.8 kB view details)

Uploaded Source

Built Distribution

drf_simple_api_errors-1.0.2-py3-none-any.whl (9.4 kB view details)

Uploaded Python 3

File details

Details for the file drf_simple_api_errors-1.0.2.tar.gz.

File metadata

  • Download URL: drf_simple_api_errors-1.0.2.tar.gz
  • Upload date:
  • Size: 6.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.8.3 CPython/3.10.14 Linux/6.5.0-1025-azure

File hashes

Hashes for drf_simple_api_errors-1.0.2.tar.gz
Algorithm Hash digest
SHA256 37253251f4c9a76766d08184ce55beda8208ff4a7ec88663dde4d60a8a1cf006
MD5 19860043c55b6b2b165ccdf7604aebcc
BLAKE2b-256 d7f3523f941b3ce75aca58c0002be47a7dcbf29c0cbfe34506a9acc05625b1b9

See more details on using hashes here.

File details

Details for the file drf_simple_api_errors-1.0.2-py3-none-any.whl.

File metadata

File hashes

Hashes for drf_simple_api_errors-1.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 bf587363e36638362cf76c45ef4f043b25e659c8aeccb19f1c2f550593bc9702
MD5 f1e749dd96790550a6f0fbb6afcf0771
BLAKE2b-256 661f381abaff9a3eaf428f01234eba20047d04c311141927948d118bbde35d91

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page