Source code for sr.comp.http.json_provider
"""JSON formatting routines."""
import datetime
import json
from enum import Enum
from typing import Any
import flask.json.provider
import simplejson
from flask import g
from werkzeug.http import http_date
from sr.comp.comp import SRComp
from sr.comp.http.query_utils import match_json_info
from sr.comp.match_period import Match
[docs]
class JsonEncoder(simplejson.JSONEncoder):
"""A JSON encoder that deals with various types used in SRComp."""
def __init__(self, *args: Any, **kwargs: Any) -> None:
# The following is required because the default JSON encoder does
# stuff with these types. We can put them back in manually ourselves
# with the 'default' method if we require. It's a bit hacky, but it
# works.
# In an ideal world, the types we deal with in 'default' would have
# appropriate '_asdict' methods.
kwargs['namedtuple_as_object'] = False
kwargs['tuple_as_array'] = False
super().__init__(*args, **kwargs)
[docs]
def default(self, obj: object) -> Any:
if isinstance(obj, Enum):
return obj.value
elif isinstance(obj, Match):
comp: SRComp = g.comp_man.get_comp()
return match_json_info(comp, obj)
elif isinstance(obj, datetime.datetime):
return http_date(obj.utctimetuple())
elif isinstance(obj, datetime.date):
return http_date(obj.timetuple())
else:
return super().default(obj)
[docs]
class JsonProvider(flask.json.provider.DefaultJSONProvider):
[docs]
def dumps(self, *args: Any, **kwargs: Any) -> str:
# Don't user super() as that also sets other things we don't want,
# namely `ensure_ascii` and `default`.
kwargs.setdefault('sort_keys', self.sort_keys)
return json.dumps(
*args,
cls=JsonEncoder, # type: ignore[arg-type]
**kwargs,
)