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

bug: Plugin "Flash Messages" not working with "Redirect" Response #3325

Closed
saltcable opened this issue Apr 6, 2024 · 7 comments · Fixed by #3420
Closed

bug: Plugin "Flash Messages" not working with "Redirect" Response #3325

saltcable opened this issue Apr 6, 2024 · 7 comments · Fixed by #3420
Assignees

Comments

@saltcable
Copy link

saltcable commented Apr 6, 2024

Litestar (2.8.0)

from litestar import Litestar, Request, get, post
from litestar.contrib.jinja import JinjaTemplateEngine
from litestar.plugins.flash import FlashConfig, FlashPlugin, flash
from litestar.response import Template, Redirect
from litestar.template.config import TemplateConfig

template_config = TemplateConfig(engine=JinjaTemplateEngine, directory="templates")
flash_plugin = FlashPlugin(config=FlashConfig(template_config=template_config))


@get('/')
async def index() -> Redirect:
    return Redirect('/login')


@get('/login')
async def login(request: Request) -> Template:
    flash(request, "Flash Test!", category="info")
    return Template(template_str='{% for f in get_flashes() %} <p>{{ f.message }}</p>{% endfor %}'
                                 '<form action="/check" method="post"><button type="submit">login</button></form>')


@post('/check')
async def check(request: Request) -> Redirect:
    flash(request, "User not Found!", category="warning")
    return Redirect('/login')


app = Litestar(plugins=[flash_plugin], route_handlers=[index,login, check], template_config=template_config)

if __name__ == '__main__':
    import uvicorn

    uvicorn.run('1:app')
INFO:     Started server process [13056]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO:     127.0.0.1:50961 - "GET / HTTP/1.1" 302 Found
INFO:     127.0.0.1:50961 - "GET /login HTTP/1.1" 200 OK
INFO:     127.0.0.1:50961 - "GET /login HTTP/1.1" 200 OK
INFO:     127.0.0.1:50961 - "POST /check HTTP/1.1" 302 Found
INFO:     127.0.0.1:50961 - "GET /login HTTP/1.1" 200 OK
INFO:     Shutting down
INFO:     Waiting for application shutdown.
INFO:     Application shutdown complete.
INFO:     Finished server process [13056]

Process finished with exit code 0

litestar

Problem: Flash Message from "POST /check" is missing at final page (screenshot above)


Flask (3.0.2)

from flask import Flask, flash, render_template_string, redirect

app = Flask(__name__)
app.secret_key = b'123'


@app.get('/')
def index() -> redirect:
    return redirect('/login')


@app.get('/login')
def login():
    flash('Flash Test!')
    return render_template_string('{% for m in get_flashed_messages() %} <p>{{ m }}</p>{% endfor %}'
                                  '<form action="/check" method="post"><button type="submit">login</button></form>')


@app.post('/check')
def check():
    flash("User not Found!")
    return redirect('/login')


if __name__ == '__main__':
    app.run()
 * Serving Flask app '2'
 * Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
 * Running on http://127.0.0.1:5000
Press CTRL+C to quit
127.0.0.1 - - [06/Apr/2024 14:50:47] "GET / HTTP/1.1" 302 -
127.0.0.1 - - [06/Apr/2024 14:50:47] "GET /login HTTP/1.1" 200 -
127.0.0.1 - - [06/Apr/2024 14:50:48] "POST /check HTTP/1.1" 302 -
127.0.0.1 - - [06/Apr/2024 14:50:48] "GET /login HTTP/1.1" 200 -

flask


Note

While we are open for sponsoring on GitHub Sponsors and
OpenCollective, we also utilize Polar.sh to engage in pledge-based sponsorship.

Check out all issues funded or available for funding on our Polar.sh dashboard

  • If you would like to see an issue prioritized, make a pledge towards it!
  • We receive the pledge once the issue is completed & verified
  • This, along with engagement in the community, helps us know which features are a priority to our users.
Fund with Polar
@provinzkraut
Copy link
Member

@euri10? 👀

@saltcable
Copy link
Author

If it helps, this is how we are doing it manually in Litestar

from litestar import Litestar, Request, get, post
from litestar.contrib.jinja import JinjaTemplateEngine
from litestar.middleware.session.server_side import ServerSideSessionConfig
from litestar.response import Template, Redirect
from litestar.template.config import TemplateConfig

template_config = TemplateConfig(engine=JinjaTemplateEngine, directory="templates")


def flash(request: Request, message: str, category: str = "primary") -> None:
    if "_messages" not in request.session:
        request.session["_messages"] = []
    request.session["_messages"].append({"message": message, "category": category})


def get_flashed_messages(request: Request) -> list[str]:
    return request.session.pop("_messages") if "_messages" in request.session else []


template_config.engine_instance.engine.globals["get_flashed_messages"] = get_flashed_messages


@get('/')
async def index() -> Redirect:
    return Redirect('/login')


@get('/login')
async def login(request: Request) -> Template:
    flash(request, "Flash Test!", category="info")
    return Template(template_str='{% for f in get_flashed_messages(request) %} <p>{{ f.message }}</p>{% endfor %}'
                                 '<form action="/check" method="post"><button type="submit">login</button></form>')


@post('/check')
async def check(request: Request) -> Redirect:
    flash(request, "User not Found!", category="warning")
    return Redirect('/login')


app = Litestar(route_handlers=[index, login, check], template_config=template_config,
               middleware=[ServerSideSessionConfig().middleware])

if __name__ == '__main__':
    import uvicorn

    uvicorn.run('1:app')
INFO:     Started server process [8416]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO:     127.0.0.1:51887 - "GET / HTTP/1.1" 302 Found
INFO:     127.0.0.1:51887 - "GET /login HTTP/1.1" 200 OK
INFO:     127.0.0.1:51887 - "POST /check HTTP/1.1" 302 Found
INFO:     127.0.0.1:51887 - "GET /login HTTP/1.1" 200 OK
INFO:     Shutting down
INFO:     Waiting for application shutdown.
INFO:     Application shutdown complete.
INFO:     Finished server process [8416]

litestar_fix

@saltcable
Copy link
Author

We hoped 'flash Messages' would be integrated into the core functionality rather than as a plugin, which can often get abandoned. It's a feature present in Flask and Django, so it's likely quite important. Nonetheless, appreciate the work done so far. Litestar is at its best and continually improving. That's wonderful. Thank you!

@peterschutt
Copy link
Contributor

Configuring Litestar via plugins is an explicit architectural decision - we also use them extensively for internal things. This plugin is in the main code base and is maintained alongside the rest of the library code so there should be no need to be concerned about commitment to its maintenance any more than any other part of the library.

@peterschutt peterschutt changed the title Plugin "Flash Messages" not wrking with "Redirect" Response (Works in Flask - Example Added) bug: Plugin "Flash Messages" not working with "Redirect" Response Apr 8, 2024
@euri10
Copy link
Contributor

euri10 commented Apr 23, 2024

ok I have the same issue now that I'm trying to switch from my implenetation (which is exactly the same as @saltcable ) to the official plugin:)

I'm not sure why I went passing the messages in the request state rather than in the session in the plugin though.

This said, this could be either fixed using the same method for passing flash messages around ie in a session (but that means the plugin requires to have the session middleware installed, we could check for that in the app_init and / or install a default config for it, I'd prefer just raise a misconfiguration error rather than providing a default config)
Or there is a way for the Redirect response to be aware of the scope state from the handler that issued the flash message, but I'm not sure that is possible.

Copy link

This issue has been closed in #3420. The change will be included in the upcoming patch release.

Copy link

github-actions bot commented Jun 2, 2024

A fix for this issue has been released in v2.9.0

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

Successfully merging a pull request may close this issue.

4 participants