Skip to content

Commit 4f18aca

Browse files
committed
Use the old JSONEncoder from flask as a default
Created a copy of the deprecated JSONEncoder used by flask and use this as a default for PyJWT. This might break for some installations which further extended the flask provided JSONEncoder. To get this working again the extension must be adjusted such that a custom Encoder can be configured.
1 parent eb738d9 commit 4f18aca

File tree

2 files changed

+29
-12
lines changed

2 files changed

+29
-12
lines changed

flask_jwt_extended/config.py

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
import json
12
from datetime import datetime
23
from datetime import timedelta
34
from datetime import timezone
5+
from typing import Any
46
from typing import Iterable
57
from typing import List
68
from typing import Optional
@@ -9,12 +11,37 @@
911
from typing import Union
1012

1113
from flask import current_app
12-
from flask.json import JSONEncoder
14+
from flask.json.provider import _default
1315
from jwt.algorithms import requires_cryptography
1416

1517
from flask_jwt_extended.typing import ExpiresDelta
1618

1719

20+
class JSONEncoder(json.JSONEncoder):
21+
"""The default JSON encoder. Handles extra types compared to the
22+
built-in :class:`json.JSONEncoder`.
23+
24+
- :class:`datetime.datetime` and :class:`datetime.date` are
25+
serialized to :rfc:`822` strings. This is the same as the HTTP
26+
date format.
27+
- :class:`decimal.Decimal` is serialized to a string.
28+
- :class:`uuid.UUID` is serialized to a string.
29+
- :class:`dataclasses.dataclass` is passed to
30+
:func:`dataclasses.asdict`.
31+
- :class:`~markupsafe.Markup` (or any object with a ``__html__``
32+
method) will call the ``__html__`` method to get a string.
33+
34+
"""
35+
36+
def default(self, o: Any) -> Any:
37+
"""Convert ``o`` to a JSON serializable type. See
38+
:meth:`json.JSONEncoder.default`. Python does not support
39+
overriding how basic types like ``str`` or ``list`` are
40+
serialized, they are handled before this method.
41+
"""
42+
return _default(o)
43+
44+
1845
class _Config(object):
1946
"""
2047
Helper object for accessing and verifying options in this extension. This
@@ -284,7 +311,7 @@ def error_msg_key(self) -> str:
284311

285312
@property
286313
def json_encoder(self) -> Type[JSONEncoder]:
287-
return current_app.json_encoder
314+
return JSONEncoder
288315

289316
@property
290317
def decode_audience(self) -> Union[str, Iterable[str]]:

tests/test_config.py

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import pytest
44
from dateutil.relativedelta import relativedelta
55
from flask import Flask
6-
from flask.json import JSONEncoder
76

87
from flask_jwt_extended import JWTManager
98
from flask_jwt_extended.config import config
@@ -65,8 +64,6 @@ def test_default_configs(app):
6564

6665
assert config.identity_claim_key == "sub"
6766

68-
assert config.json_encoder is app.json_encoder
69-
7067
assert config.error_msg_key == "msg"
7168

7269

@@ -112,11 +109,6 @@ def test_override_configs(app, delta_func):
112109

113110
app.config["JWT_ERROR_MESSAGE_KEY"] = "message"
114111

115-
class CustomJSONEncoder(JSONEncoder):
116-
pass
117-
118-
app.json_encoder = CustomJSONEncoder
119-
120112
with app.test_request_context():
121113
assert config.token_location == ["cookies", "query_string", "json"]
122114
assert config.jwt_in_query_string is True
@@ -162,8 +154,6 @@ class CustomJSONEncoder(JSONEncoder):
162154

163155
assert config.identity_claim_key == "foo"
164156

165-
assert config.json_encoder is CustomJSONEncoder
166-
167157
assert config.error_msg_key == "message"
168158

169159

0 commit comments

Comments
 (0)