flask-session icon indicating copy to clipboard operation
flask-session copied to clipboard

Flash message with Markup fails

Open jeroen-80 opened this issue 11 months ago • 2 comments

Upgrading my platform from Python 3.8 + Flask 3.0.3 + Flask-Session 0.8.0 with redis backend, to Python 3.11 + Flask 3.1.0 + Flask-Session 0.8.0 with redis backend. Same user code.

Issue: fancy flash message breaks on the new platform (work fine on the old platform).

Flash message: flash(Markup('press the play button <i class="bi-play-btn-fill black"></i> below'), 'info')

Error:

[2024-12-10 19:01:28,998] ERROR in base: Failed to serialize session data: Encoding objects of type Markup is unsupported
[2024-12-10 19:01:28,998] ERROR in app: Exception on / [POST]
Traceback (most recent call last):
  File "/var/www/lib/python3.11/site-packages/flask/app.py", line 1511, in wsgi_app
    response = self.full_dispatch_request()
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/var/www/lib/python3.11/site-packages/flask/app.py", line 920, in full_dispatch_request
    return self.finalize_request(rv)
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/var/www/lib/python3.11/site-packages/flask/app.py", line 941, in finalize_request
    response = self.process_response(response)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/var/www/lib/python3.11/site-packages/flask/app.py", line 1322, in process_response
    self.session_interface.save_session(self, ctx.session, response)
  File "/var/www/lib/python3.11/site-packages/flask_session/base.py", line 305, in save_session
    self._upsert_session(app.permanent_session_lifetime, session, store_id)
  File "/var/www/lib/python3.11/site-packages/flask_session/redis/redis.py", line 78, in _upsert_session
    serialized_session_data = self.serializer.encode(session)
                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/var/www/lib/python3.11/site-packages/flask_session/base.py", line 132, in encode
    return self.encoder.encode(dict(session))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: Encoding objects of type Markup is unsupported
[2024-12-10 19:01:29,002] ERROR in base: Failed to serialize session data: Encoding objects of type Markup is unsupported
[2024-12-10 19:01:29,002] ERROR in app: Request finalizing failed with an error while handling an error
Traceback (most recent call last):
  File "/var/www/lib/python3.11/site-packages/flask/app.py", line 1511, in wsgi_app
    response = self.full_dispatch_request()
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/var/www/lib/python3.11/site-packages/flask/app.py", line 920, in full_dispatch_request
    return self.finalize_request(rv)
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/var/www/lib/python3.11/site-packages/flask/app.py", line 941, in finalize_request
    response = self.process_response(response)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/var/www/lib/python3.11/site-packages/flask/app.py", line 1322, in process_response
    self.session_interface.save_session(self, ctx.session, response)
  File "/var/www/lib/python3.11/site-packages/flask_session/base.py", line 305, in save_session
    self._upsert_session(app.permanent_session_lifetime, session, store_id)
  File "/var/www/lib/python3.11/site-packages/flask_session/redis/redis.py", line 78, in _upsert_session
    serialized_session_data = self.serializer.encode(session)
                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/var/www/lib/python3.11/site-packages/flask_session/base.py", line 132, in encode
    return self.encoder.encode(dict(session))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: Encoding objects of type Markup is unsupported

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/var/www/lib/python3.11/site-packages/flask/app.py", line 941, in finalize_request
    response = self.process_response(response)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/var/www/lib/python3.11/site-packages/flask/app.py", line 1322, in process_response
    self.session_interface.save_session(self, ctx.session, response)
  File "/var/www/lib/python3.11/site-packages/flask_session/base.py", line 305, in save_session
    self._upsert_session(app.permanent_session_lifetime, session, store_id)
  File "/var/www/lib/python3.11/site-packages/flask_session/redis/redis.py", line 78, in _upsert_session
    serialized_session_data = self.serializer.encode(session)
                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/var/www/lib/python3.11/site-packages/flask_session/base.py", line 132, in encode
    return self.encoder.encode(dict(session))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: Encoding objects of type Markup is unsupported

jeroen-80 avatar Dec 10 '24 18:12 jeroen-80

Same error here, any foreseen fix date for this?

Using Python 3.12, flask-session 0.8.0, flask==3.1.0 with redis backend.

Some simple Markup works, e.g. Markup(f'{msg}<br/>{errors}') while other don't

neurino avatar Feb 25 '25 10:02 neurino

I found the same issue and found it to be inconsistent (or so I thought). If you set a flash message before rendering the page it will work fine, but if you set the flash message and then redirect then it wont work.

This sort of make sense because when just rendering the page it does not actually need to preserve the flash message in the session between requests but it will do for a redirect.

The actual reason, I think, this is happening is that Markup is not a supported type for msgspec

tim-s-ccs avatar Apr 07 '25 16:04 tim-s-ccs

We have the same problem with Airlfow - we are preparing to migrate to upcoming connextion 2.15 and running tests with flask-session>=7.9.0 that it will require and I have the very same issue https://github.com/apache/airflow/actions/runs/16130446818/job/45516933293#step:6:3748

Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/flask_session/_utils.py", line 52, in wrapper
    return func(*args, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/flask_session/sqlalchemy/sqlalchemy.py", line 171, in _upsert_session
    serialized_session_data = self.serializer.encode(session)
  File "/usr/local/lib/python3.9/site-packages/flask_session/base.py", line 132, in encode
    return self.encoder.encode(dict(session))
TypeError: Encoding objects of type Markup is unsupported
ERROR    airflow.www.app:base.py:134 Failed to serialize session data: Encoding objects of type Markup is unsupported

The only solution I have found so far is to go back to json serializer and some people even went ahead to define their own serializers https://github.com/ckan/ckan/pull/8704/files#diff-3fcde3a06f17437374b4510cc0c57d62477501f8825063fa84b6e1509e6ab93bR77-R92

I think it would be great to make it possible to serialize Markup with MsgSpec, but I guess simply switching to JSON serializer is the solution for now.

potiuk avatar Jul 08 '25 07:07 potiuk