Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

'data_serializer': 'json' causes TypeError: Object of type datetime is not JSON serializable caused by on _expires attribute #247

Open
JamieBeverley opened this issue Mar 11, 2025 · 0 comments

Comments

@JamieBeverley
Copy link

Overview

Using session.data_serializer=json produces the following error (full stack trace below):

TypeError: Object of type datetime is not JSON serializable

Details

  • The _expires attribute is set on a CookieSession to a datetime object here
  • When that cookie is serialized to json, an error is through as datetimes are not JSON serializable
  • This error seems to only occur after the 2nd time a cookie is .save()d: only after the first .save() the _expires attribute is set to a datetime on the cookie and then subsequent uses of the cookie fail at serialization.

Reproducible Example

Test Case

from beaker.session import CookieSession

COOKIE_REQUEST = {}

options = {
    'invalidate_corrupt': True,
    'type': 'cookie',
    'data_dir': None,
    'key': 'ckan',
    'timeout': None,
    'save_accessed_time': True,
    'secret': '12341234',
    'log_file': None,
    'data_serializer': 'json',
    'validate_key': 'asdfasdf',
    'httponly': True,
    'secure': False,
    'samesite': 'Strict',
    'auto': False,
    'cookie_expires': False,
    'cookie_domain': None
}

def test_cookie_serialize_json_can_be_saved():
    cookie_session = CookieSession(COOKIE_REQUEST, **options)
    cookie_session.save()
    # 2nd call to .save() causes the error
    cookie_session.save()

if __name__=='__main__':
    test_cookie_serialize_json_can_be_saved()

Flask

  • open localhost:5000 -> expect to load fine the first time
  • refresh the page -> json serialization error
from flask import Flask, request
from beaker.middleware import SessionMiddleware

app = Flask(__name__)

session_opts = {
    'session.key': 'session-key',
    'session.secret': '12341234',
    'session.type': 'cookie',
    'session.data_serializer': 'json',
    'session.validate_key': 'asdfasdf',
    'session.httponly': True,
    'session.secure': False,
    'session.samesite': 'Strict',
    'session.auto': False,
    'session.cookie_expires': False,
    'session.cookie_domain': None,
    'session.save_accessed_time': True,
    'session.timeout': None,
}

app.wsgi_app = SessionMiddleware(app.wsgi_app, session_opts)

@app.route('/', methods=['GET'])
def set_session():
    session = request.environ['beaker.session']
    session['count'] = session.get('count',0) + 1
    session.save()
    return f"<h1>Session updated</h1><p>Session: <code>{session}</code></p>"

if __name__ == '__main__':
    app.run(debug=True)

Full Stack Trace

Traceback (most recent call last):
  File ".../beaker-test/repro.py", line 29, in <module>
    test_cookie_serialize_json_can_be_saved()
  File ".../beaker-test/repro.py", line 27, in test_cookie_serialize_json_can_be_saved
    cookie_session.save()
  File ".../beaker-test/beaker/beaker/session.py", line 723, in save
    self._create_cookie()
  File ".../beaker-test/beaker/beaker/session.py", line 737, in _create_cookie
    val = self._encrypt_data()
          ^^^^^^^^^^^^^^^^^^^^
  File ".../beaker-test/beaker/beaker/session.py", line 381, in _encrypt_data
    data = self.serializer.dumps(session_data)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../beaker-test/beaker/beaker/util.py", line 469, in dumps
    return zlib.compress(json.dumps(data).encode('utf-8'))
                         ^^^^^^^^^^^^^^^^
  File ".../python/3.11.10/lib/python3.11/json/__init__.py", line 231, in dumps
    return _default_encoder.encode(obj)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../python/3.11.10/lib/python3.11/json/encoder.py", line 200, in encode
    chunks = self.iterencode(o, _one_shot=True)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../python/3.11.10/lib/python3.11/json/encoder.py", line 258, in iterencode
    return _iterencode(o, 0)
           ^^^^^^^^^^^^^^^^^
  File ".../python/3.11.10/lib/python3.11/json/encoder.py", line 180, in default
    raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type datetime is not JSON serializable
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant