OpenAPI Schema Generation
=========================

``django-mantle-drf`` integrates with `drf-spectacular
<https://drf-spectacular.readthedocs.io/>`_ to generate OpenAPI schemas from
attrs shape classes.

Setup
-----

Install the extras:

.. code-block:: bash

   pip install "django-mantle-drf[spectacular]"

Add ``drf_spectacular`` to ``INSTALLED_APPS`` and configure the schema class:

.. code-block:: python

   INSTALLED_APPS = [
       ...
       "drf_spectacular",
   ]

   REST_FRAMEWORK = {
       "DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema",
   }

Register the Extension
----------------------

Import ``mantle_drf.schema`` in your ``AppConfig.ready()`` to register the
attrs extension with drf-spectacular:

.. code-block:: python

   from django.apps import AppConfig

   class MyAppConfig(AppConfig):
       name = "myapp"

       def ready(self):
           import mantle_drf.schema  # noqa: F401

Annotate Views
--------------

Use ``@extend_schema`` with attrs classes as ``request`` and ``responses``:

.. code-block:: python

   from drf_spectacular.utils import extend_schema
   from mantle_drf.generics import RetrieveAPIView
   from .shapes import BookmarkShape

   class BookmarkDetail(RetrieveAPIView):
       queryset = Bookmark.objects.all()
       shape_class = BookmarkShape

       @extend_schema(responses=BookmarkShape)
       def get(self, request, *args, **kwargs):
           return self.retrieve(request, *args, **kwargs)

The generated schema will include a ``BookmarkShape`` component with correct
property types, derived from the attrs class via ``jsonschema-extractor``.

Field Metadata
--------------

Use attrs field metadata to add OpenAPI hints:

.. code-block:: python

   @attr.define
   class EventShape:
       name: str
       created_at: str = attr.field(
           metadata={"jsonschema": {"type": "string", "format": "date-time"}}
       )
       description: str = attr.field(
           default="",
           metadata={"description": "Optional event description"},
       )
