# GSOC 2023 Discussion on Configurable Content Type Parsing

**URL:** <https://forum.djangoproject.com/t/gsoc-2023-discussion-on-configurable-content-type-parsing/19556>\
**Category:** Google Season of Code\
**Created:** [March 16, 2023, 11:41am UTC](https://forum.djangoproject.com/t/gsoc-2023-discussion-on-configurable-content-type-parsing/19556 "2023-03-16T11:41:22Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Akash-Kumar-Sen](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/akash-kumar-sen/32/12736_2.png) [@Akash-Kumar-Sen](https://forum.djangoproject.com/u/Akash-Kumar-Sen)\
**Post date:** [March 16, 2023, 11:41am UTC](https://forum.djangoproject.com/t/gsoc-2023-discussion-on-configurable-content-type-parsing/19556/1 "2023-03-16T11:41:22Z")

</div>

Hi everyone,  
I want to contribute to this project as a part of GSOC 2023. I have never contributed to any of the official Django projects earlier but I have experience using the framework for last 2 years. In this discussion I would like to propose a high level view of how this can be implemented, any kind of feedback and reference to resources for a more detailed and clear perspective about the project from your side would be very much appreciated, before I start writing the proposal.

**Project Title : Configurable Content Type Parsing**  
**Project Description(Given):**  
For Django 5.0 we’re looking to modernize the `HTTPRequest` object, adding a content-type aware `request.data` property. This will parse `request.body` according to the content type.

The initial phase — targeted for before GSoC — will add `request.data` and add support for JSON body handling, but the next phase is to make that fully pluggable with custom parsers.

- Add a list of parsers to the request object, that can be customised — in a middleware for example — at any point prior to accessing `request.data`.
- Parsers should implement a `can_handle(content_type) -> Bool` method. The first parser returning True will be selected to parse the `request.body`.

Expected outcome is a PR allowing configurable content type parsing.

**High level thoughts on implementation :**

**Step 1:** Add a `parsers` list to the `HttpRequest` object :  
We’ll start by adding a `parsers` list to the `HttpRequest` object that will contain instances of parser classes. This list will be empty by default, and will be populated by custom parsers added via middleware.

**Step 2:** Define a `Parser` abstract class  
We’ll define a `Parser` abstract class that all custom parsers must inherit from. This abstract class should define the `can_handle(content_type) -> Bool` method that checks whether the parser can handle the given content type.

**Step 3:** Implement a default `JSONParser` class  
We’ll implement a default `JSONParser` class that inherits from `Parser` and handles JSON request bodies. This parser will be added to the `parsers` list by default.

**Possible high level code example**

```auto
import json

class JSONParser(Parser):
    def can_handle(self, content_type):
        return content_type == 'application/json'

    def parse(self, body):
        return json.loads(body.decode('utf-8'))

```

**Step 4 :** Add a `data` property to the `HttpRequest` object  
We’ll add a `data` property to the `HttpRequest` object that will be responsible for parsing the request body. This property should first check the content type of the request, and then iterate through the `parsers` list to find the first parser that can handle the content type. If a parser is found, it should be used to parse the request body, and the parsed data should be returned. If no parser can handle the content type, a `UnsupportedMediaType` exception should be raised.

**Possible high level code example**

```auto
from django.http import UnsupportedMediaType

class HttpRequest:
    def __init__ (self):
       .......code........
        self.parsers = [JSONParser()]

    @property
    def data(self):
        content_type = self.headers.get('Content-Type', '')
        for parser in self.parsers:
            if parser.can_handle(content_type):
                return parser.parse(self.body)
        raise UnsupportedMediaType('Unsupported content type: {}'.format(content_type))

```

**Step 5:** Allow customization of the `parsers` list via middleware  
We’ll allow customization of the `parsers` list by providing a way to add or remove parsers. This can be done by adding methods to the middleware that allow adding and removing parsers from the `parsers` list.

**Possible high level code example**

```auto
class CustomParserMiddleware:
    def __init__ (self, get_response):
        self.get_response = get_response

    def __call__ (self, request):
        # Add custom parsers here
        request.parsers.append(CustomParser())

        response = self.get_response(request)

        return response

```

**Step 6:** Document the changes and add appropriate tests  
Finally, we’ll document the changes and add appropriate tests to ensure the new functionality is working as expected. We should test that the default `JSONParser` is able to parse JSON request bodies correctly, and that custom parsers added via middleware are able to parse request bodies of their specified content types.

Due to my beginner level understanding of the codebase there is a lot of scope room for improvement. Your suggestions willbe of great help.

---

<div class="post-metadata">

**Author:** ![Akash-Kumar-Sen](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/akash-kumar-sen/32/12736_2.png) [@Akash-Kumar-Sen](https://forum.djangoproject.com/u/Akash-Kumar-Sen)\
**Post date:** [March 16, 2023, 11:46am UTC](https://forum.djangoproject.com/t/gsoc-2023-discussion-on-configurable-content-type-parsing/19556/2 "2023-03-16T11:46:20Z")

</div>

@carltongibson If you can have a look at this and let me know that would be of great help!

---

<div class="post-metadata">

**Author:** ![carltongibson](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/carltongibson/32/267_2.png) [@carltongibson](https://forum.djangoproject.com/u/carltongibson)\
**Post date:** [March 23, 2023, 8:02am UTC](https://forum.djangoproject.com/t/gsoc-2023-discussion-on-configurable-content-type-parsing/19556/3 "2023-03-23T08:02:48Z")

</div>

Hi @Akash-Kumar-Sen — sorry for the slow reply. _Life_.

Do submit your proposals. Exact API details can be decided in the project phase. The goal here is for you to demonstrate a clear grasp of the issue.

Kind Regards,

Carlton
