drf-toon 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- drf_toon-0.1.0/PKG-INFO +106 -0
- drf_toon-0.1.0/README.md +93 -0
- drf_toon-0.1.0/pyproject.toml +78 -0
- drf_toon-0.1.0/pyproject.toml.orig +73 -0
- drf_toon-0.1.0/src/drf_toon/__init__.py +0 -0
- drf_toon-0.1.0/src/drf_toon/apps.py +6 -0
- drf_toon-0.1.0/src/drf_toon/parsers.py +20 -0
- drf_toon-0.1.0/src/drf_toon/renderers.py +10 -0
drf_toon-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: drf-toon
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Native TOON parser and renderer for Django Rest Framework.
|
|
5
|
+
Author: Dash Winterson
|
|
6
|
+
Author-email: Dash Winterson <dashdanw@gmail.com>
|
|
7
|
+
Requires-Dist: django>=5.2,<6.0
|
|
8
|
+
Requires-Dist: djangorestframework>=3.15
|
|
9
|
+
Requires-Dist: djangorestframework-stubs>=3.15
|
|
10
|
+
Requires-Dist: toons>=0.7.0
|
|
11
|
+
Requires-Python: >=3.10
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
|
|
14
|
+
# drf-toon
|
|
15
|
+
|
|
16
|
+
Native [TOON](https://toonformat.dev/) (Token Oriented Object Notation) parser and renderer for [Django REST Framework](https://www.django-rest-framework.org/).
|
|
17
|
+
|
|
18
|
+
TOON is a token-efficient serialization format designed for LLM contexts. It can result in **30–60% fewer tokens** than JSON.
|
|
19
|
+
|
|
20
|
+
`drf-toon` is built on [`toons`](https://github.com/alesanfra/toons), a high-performance Rust implementation meant to mimic the native python `json` package.
|
|
21
|
+
|
|
22
|
+
## Compatibility
|
|
23
|
+
|
|
24
|
+
`drf-toon` supports **Django 5.2 LTS** on **Python 3.10–3.13**, matching
|
|
25
|
+
Django's own [support matrix](https://docs.djangoproject.com/en/stable/faq/install/#what-python-version-can-i-use-with-django).
|
|
26
|
+
Every supported Python version is exercised in CI.
|
|
27
|
+
|
|
28
|
+
| Django | Python |
|
|
29
|
+
| ------- | ---------------------- |
|
|
30
|
+
| 5.2 LTS | 3.10, 3.11, 3.12, 3.13 |
|
|
31
|
+
|
|
32
|
+
Support for additional Django releases can be added later by extending the CI
|
|
33
|
+
matrix.
|
|
34
|
+
|
|
35
|
+
## Installation
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
pip install drf-toon
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Usage
|
|
42
|
+
|
|
43
|
+
Add the parser and renderer to your DRF settings:
|
|
44
|
+
|
|
45
|
+
```python
|
|
46
|
+
# settings.py
|
|
47
|
+
REST_FRAMEWORK = {
|
|
48
|
+
"DEFAULT_PARSER_CLASSES": [
|
|
49
|
+
"drf_toon.parsers.TOONParser",
|
|
50
|
+
"rest_framework.parsers.JSONParser",
|
|
51
|
+
],
|
|
52
|
+
"DEFAULT_RENDERER_CLASSES": [
|
|
53
|
+
"drf_toon.renderers.TOONRenderer",
|
|
54
|
+
"rest_framework.renderers.JSONRenderer",
|
|
55
|
+
],
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Or enable them per-view:
|
|
60
|
+
|
|
61
|
+
```python
|
|
62
|
+
from rest_framework.views import APIView
|
|
63
|
+
from rest_framework.response import Response
|
|
64
|
+
|
|
65
|
+
from drf_toon.parsers import TOONParser
|
|
66
|
+
from drf_toon.renderers import TOONRenderer
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class UserView(APIView):
|
|
70
|
+
parser_classes = [TOONParser]
|
|
71
|
+
renderer_classes = [TOONRenderer]
|
|
72
|
+
|
|
73
|
+
def get(self, request):
|
|
74
|
+
return Response({"name": "Alice", "age": 30})
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Both classes use the `application/toon` media type. Send requests with
|
|
78
|
+
`Content-Type: application/toon` to parse, and `Accept: application/toon`
|
|
79
|
+
(or `?format=toon`) to render.
|
|
80
|
+
|
|
81
|
+
## Development
|
|
82
|
+
|
|
83
|
+
Install the dev dependencies and run the checks with uv:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
uv sync --dev
|
|
87
|
+
|
|
88
|
+
uv run ruff check . # lint
|
|
89
|
+
uv run ruff format . # format
|
|
90
|
+
uv run ruff format --check . # format check (CI)
|
|
91
|
+
uv run mypy # type check
|
|
92
|
+
uv run pytest # tests + coverage
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Optionally install the git hooks:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
uv run pre-commit install --install-hooks
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
This wires up both a **pre-commit** hook (autofix + format) and a **pre-push**
|
|
102
|
+
hook that blocks the push if the code is not properly linted/formatted.
|
|
103
|
+
|
|
104
|
+
## License
|
|
105
|
+
|
|
106
|
+
MIT
|
drf_toon-0.1.0/README.md
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# drf-toon
|
|
2
|
+
|
|
3
|
+
Native [TOON](https://toonformat.dev/) (Token Oriented Object Notation) parser and renderer for [Django REST Framework](https://www.django-rest-framework.org/).
|
|
4
|
+
|
|
5
|
+
TOON is a token-efficient serialization format designed for LLM contexts. It can result in **30–60% fewer tokens** than JSON.
|
|
6
|
+
|
|
7
|
+
`drf-toon` is built on [`toons`](https://github.com/alesanfra/toons), a high-performance Rust implementation meant to mimic the native python `json` package.
|
|
8
|
+
|
|
9
|
+
## Compatibility
|
|
10
|
+
|
|
11
|
+
`drf-toon` supports **Django 5.2 LTS** on **Python 3.10–3.13**, matching
|
|
12
|
+
Django's own [support matrix](https://docs.djangoproject.com/en/stable/faq/install/#what-python-version-can-i-use-with-django).
|
|
13
|
+
Every supported Python version is exercised in CI.
|
|
14
|
+
|
|
15
|
+
| Django | Python |
|
|
16
|
+
| ------- | ---------------------- |
|
|
17
|
+
| 5.2 LTS | 3.10, 3.11, 3.12, 3.13 |
|
|
18
|
+
|
|
19
|
+
Support for additional Django releases can be added later by extending the CI
|
|
20
|
+
matrix.
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pip install drf-toon
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Usage
|
|
29
|
+
|
|
30
|
+
Add the parser and renderer to your DRF settings:
|
|
31
|
+
|
|
32
|
+
```python
|
|
33
|
+
# settings.py
|
|
34
|
+
REST_FRAMEWORK = {
|
|
35
|
+
"DEFAULT_PARSER_CLASSES": [
|
|
36
|
+
"drf_toon.parsers.TOONParser",
|
|
37
|
+
"rest_framework.parsers.JSONParser",
|
|
38
|
+
],
|
|
39
|
+
"DEFAULT_RENDERER_CLASSES": [
|
|
40
|
+
"drf_toon.renderers.TOONRenderer",
|
|
41
|
+
"rest_framework.renderers.JSONRenderer",
|
|
42
|
+
],
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Or enable them per-view:
|
|
47
|
+
|
|
48
|
+
```python
|
|
49
|
+
from rest_framework.views import APIView
|
|
50
|
+
from rest_framework.response import Response
|
|
51
|
+
|
|
52
|
+
from drf_toon.parsers import TOONParser
|
|
53
|
+
from drf_toon.renderers import TOONRenderer
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class UserView(APIView):
|
|
57
|
+
parser_classes = [TOONParser]
|
|
58
|
+
renderer_classes = [TOONRenderer]
|
|
59
|
+
|
|
60
|
+
def get(self, request):
|
|
61
|
+
return Response({"name": "Alice", "age": 30})
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Both classes use the `application/toon` media type. Send requests with
|
|
65
|
+
`Content-Type: application/toon` to parse, and `Accept: application/toon`
|
|
66
|
+
(or `?format=toon`) to render.
|
|
67
|
+
|
|
68
|
+
## Development
|
|
69
|
+
|
|
70
|
+
Install the dev dependencies and run the checks with uv:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
uv sync --dev
|
|
74
|
+
|
|
75
|
+
uv run ruff check . # lint
|
|
76
|
+
uv run ruff format . # format
|
|
77
|
+
uv run ruff format --check . # format check (CI)
|
|
78
|
+
uv run mypy # type check
|
|
79
|
+
uv run pytest # tests + coverage
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Optionally install the git hooks:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
uv run pre-commit install --install-hooks
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
This wires up both a **pre-commit** hook (autofix + format) and a **pre-push**
|
|
89
|
+
hook that blocks the push if the code is not properly linted/formatted.
|
|
90
|
+
|
|
91
|
+
## License
|
|
92
|
+
|
|
93
|
+
MIT
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "drf-toon"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "Native TOON parser and renderer for Django Rest Framework."
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.10"
|
|
7
|
+
dependencies = [
|
|
8
|
+
"django>=5.2,<6.0",
|
|
9
|
+
"djangorestframework>=3.15",
|
|
10
|
+
"djangorestframework-stubs>=3.15",
|
|
11
|
+
"toons>=0.7.0",
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
[[project.authors]]
|
|
15
|
+
name = "Dash Winterson"
|
|
16
|
+
email = "dashdanw@gmail.com"
|
|
17
|
+
|
|
18
|
+
[build-system]
|
|
19
|
+
requires = ["uv_build>=0.11.24,<0.12.0"]
|
|
20
|
+
build-backend = "uv_build"
|
|
21
|
+
|
|
22
|
+
[dependency-groups]
|
|
23
|
+
dev = [
|
|
24
|
+
"drf-spectacular>=0.27.0",
|
|
25
|
+
"mypy>=1.10.0",
|
|
26
|
+
"pre-commit>=3.7.0",
|
|
27
|
+
"pytest>=8.0.0",
|
|
28
|
+
"pytest-cov>=5.0.0",
|
|
29
|
+
"pytest-django>=4.8.0",
|
|
30
|
+
"ruff>=0.6.0",
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
[tool.pytest.ini_options]
|
|
34
|
+
python_files = ["test_*.py"]
|
|
35
|
+
testpaths = ["tests"]
|
|
36
|
+
addopts = "--cov=drf_toon --cov-report=term-missing"
|
|
37
|
+
|
|
38
|
+
[tool.ruff]
|
|
39
|
+
line-length = 100
|
|
40
|
+
target-version = "py310"
|
|
41
|
+
src = [
|
|
42
|
+
"src",
|
|
43
|
+
"tests",
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
[tool.ruff.lint]
|
|
47
|
+
select = [
|
|
48
|
+
"E",
|
|
49
|
+
"W",
|
|
50
|
+
"F",
|
|
51
|
+
"I",
|
|
52
|
+
"B",
|
|
53
|
+
"UP",
|
|
54
|
+
"C4",
|
|
55
|
+
]
|
|
56
|
+
ignore = []
|
|
57
|
+
|
|
58
|
+
[tool.ruff.lint.isort]
|
|
59
|
+
known-first-party = ["drf_toon"]
|
|
60
|
+
|
|
61
|
+
[tool.ruff.format]
|
|
62
|
+
quote-style = "double"
|
|
63
|
+
|
|
64
|
+
[tool.mypy]
|
|
65
|
+
python_version = "3.10"
|
|
66
|
+
files = [
|
|
67
|
+
"src",
|
|
68
|
+
"tests",
|
|
69
|
+
]
|
|
70
|
+
ignore_missing_imports = true
|
|
71
|
+
warn_unused_ignores = true
|
|
72
|
+
warn_redundant_casts = true
|
|
73
|
+
|
|
74
|
+
[tool.coverage.run]
|
|
75
|
+
source = ["drf_toon"]
|
|
76
|
+
|
|
77
|
+
[tool.coverage.report]
|
|
78
|
+
show_missing = true
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "drf-toon"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "Native TOON parser and renderer for Django Rest Framework."
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
authors = [
|
|
7
|
+
{ name = "Dash Winterson", email = "dashdanw@gmail.com" }
|
|
8
|
+
]
|
|
9
|
+
requires-python = ">=3.10"
|
|
10
|
+
dependencies = [
|
|
11
|
+
"django>=5.2,<6.0",
|
|
12
|
+
"djangorestframework>=3.15",
|
|
13
|
+
"djangorestframework-stubs>=3.15",
|
|
14
|
+
"toons>=0.7.0",
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
[build-system]
|
|
18
|
+
requires = ["uv_build>=0.11.24,<0.12.0"]
|
|
19
|
+
build-backend = "uv_build"
|
|
20
|
+
|
|
21
|
+
[dependency-groups]
|
|
22
|
+
dev = [
|
|
23
|
+
"drf-spectacular>=0.27.0",
|
|
24
|
+
"mypy>=1.10.0",
|
|
25
|
+
"pre-commit>=3.7.0",
|
|
26
|
+
"pytest>=8.0.0",
|
|
27
|
+
"pytest-cov>=5.0.0",
|
|
28
|
+
"pytest-django>=4.8.0",
|
|
29
|
+
"ruff>=0.6.0",
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
[tool.pytest.ini_options]
|
|
34
|
+
python_files = ["test_*.py"]
|
|
35
|
+
testpaths = ["tests"]
|
|
36
|
+
addopts = "--cov=drf_toon --cov-report=term-missing"
|
|
37
|
+
|
|
38
|
+
[tool.ruff]
|
|
39
|
+
line-length = 100
|
|
40
|
+
target-version = "py310"
|
|
41
|
+
src = ["src", "tests"]
|
|
42
|
+
|
|
43
|
+
[tool.ruff.lint]
|
|
44
|
+
select = [
|
|
45
|
+
"E", # pycodestyle errors
|
|
46
|
+
"W", # pycodestyle warnings
|
|
47
|
+
"F", # pyflakes
|
|
48
|
+
"I", # isort
|
|
49
|
+
"B", # flake8-bugbear
|
|
50
|
+
"UP", # pyupgrade
|
|
51
|
+
"C4", # flake8-comprehensions
|
|
52
|
+
]
|
|
53
|
+
ignore = []
|
|
54
|
+
|
|
55
|
+
[tool.ruff.lint.isort]
|
|
56
|
+
known-first-party = ["drf_toon"]
|
|
57
|
+
|
|
58
|
+
[tool.ruff.format]
|
|
59
|
+
quote-style = "double"
|
|
60
|
+
|
|
61
|
+
[tool.mypy]
|
|
62
|
+
python_version = "3.10"
|
|
63
|
+
files = ["src", "tests"]
|
|
64
|
+
ignore_missing_imports = true
|
|
65
|
+
warn_unused_ignores = true
|
|
66
|
+
warn_redundant_casts = true
|
|
67
|
+
|
|
68
|
+
[tool.coverage.run]
|
|
69
|
+
source = ["drf_toon"]
|
|
70
|
+
|
|
71
|
+
[tool.coverage.report]
|
|
72
|
+
show_missing = true
|
|
73
|
+
|
|
File without changes
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import codecs
|
|
2
|
+
|
|
3
|
+
import toons
|
|
4
|
+
from django.conf import settings
|
|
5
|
+
from rest_framework.exceptions import ParseError
|
|
6
|
+
from rest_framework.parsers import BaseParser
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class TOONParser(BaseParser):
|
|
10
|
+
media_type = "application/toon"
|
|
11
|
+
|
|
12
|
+
def parse(self, stream, media_type=None, parser_context=None):
|
|
13
|
+
parser_context = parser_context or {}
|
|
14
|
+
encoding = parser_context.get("encoding", settings.DEFAULT_CHARSET)
|
|
15
|
+
decoded_stream = codecs.getreader(encoding)(stream)
|
|
16
|
+
|
|
17
|
+
try:
|
|
18
|
+
return toons.load(decoded_stream)
|
|
19
|
+
except toons.ToonDecodeError as e:
|
|
20
|
+
raise ParseError(f"TOON parse error - {str(e)}") from e
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import toons
|
|
2
|
+
from rest_framework.renderers import BaseRenderer
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class TOONRenderer(BaseRenderer):
|
|
6
|
+
media_type = "application/toon"
|
|
7
|
+
format = "toon"
|
|
8
|
+
|
|
9
|
+
def render(self, data, accepted_media_type=None, renderer_context=None):
|
|
10
|
+
return toons.dumps(data).encode(self.charset)
|