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

Flash messages support #25

Open
jettify opened this issue Jan 3, 2016 · 9 comments
Open

Flash messages support #25

jettify opened this issue Jan 3, 2016 · 9 comments

Comments

@jettify
Copy link
Member

jettify commented Jan 3, 2016

Do we need some sort of flash messages support? Or may be this feature is out of scope of aiohttp_session?

Most frameworks have flash messages:
pyramid: http://docs.pylonsproject.org/projects/pyramid/en/1.0-branch/narr/sessions.html#flash-messages
flask: http://flask.pocoo.org/docs/0.10/patterns/flashing/

Particularly pyramid has it integrated to session object.

@imbolc
Copy link
Contributor

imbolc commented Jan 4, 2016

I think it will look better as a separate package because it brings some dependencies like aiohttp_jinja2 for context_processor implementation.

@jettify
Copy link
Member Author

jettify commented Jan 4, 2016

Do not follow, it is couple of methods:
flash() - add message to the queue, where queue is located in session object
pop_flash() - pop messages from the queue

Do not see why it should depend on aiohttp_jinja2

@imbolc
Copy link
Contributor

imbolc commented Jan 4, 2016

Because flash messages doesn't make much sense without templates. And I think there is not so much code to split it into parts. Exactly it took 22 loc in my last implementation: https://gist.github.com/imbolc/ca43545ca31329b4f9e2

@imbolc
Copy link
Contributor

imbolc commented Jan 4, 2016

Also, this approach has benefits of brevity:

flash(request, ('error', 'Foo error'))

instead of

session = await get_session(request)
session.flash(request, ('error', 'Foo error'))

@asvetlov
Copy link
Member

asvetlov commented Jan 4, 2016

@imbolc request is not necessary in your last example. session is coupled to request itself.
Anyway, let's postpone the issue.
For now I have a feeling that flash messages are part of UI library (while they are built on top of user session, sure).

Another interesting question is API for CSRF checks BTW.

@shicky
Copy link
Contributor

shicky commented May 13, 2016

I also do not understand how flash depends on template engine.
As @asvetlov mentioned, flash is necessary to implement CSRF check.

@IlyaSemenov
Copy link

I created the simple session flash library based on @imbolc's gist:

https://github.com/IlyaSemenov/aiohttp_session_flash

It has a few enhancements over the original gist:

  • session is not re-saved on each HTTP request unless flash messages were pushed or popped
  • it doesn't lose flash messages followed by raise web.HTTPFound(...)
  • it has tests and pypi package

@bitnom
Copy link

bitnom commented Mar 4, 2020

I did not know about the flash example and I implemented my own thing. I didn't use middleware though. I did this:

class Session:
    def __init__(self, session):
        self.session = session

    async def get(self, getter):
        return self.session[getter] if getter in self.session else None

    async def set(self, setter, content):
        self.session[setter] = content

Is the middleware just so that we can access via request? Would be great to have the flash example commented.

@wagnerc4
Copy link

wagnerc4 commented Jun 16, 2022

Here is my super flash function: (I used with jinja2)

flash.py

from functools import partial
from aiohttp_session import Session

def message(session: Session, message: str, level: str = "info") -> None:
    session.setdefault("flash", []).append((message, level))

debug = partial(message, level="debug")
info = partial(message, level="info")
success = partial(message, level="success")
warning = partial(message, level="warning")
error = partial(message, level="danger")

app.py

import flash
from aiohttp import web
from aiohttp_jinja2 import setup as set_jinja
from aiohttp_session import get_session, setup as set_session
from jinja2 import FileSystemLoader

@template('index.html')
async def index(rq: web.Request):
    session = await get_session(rq)
    flash.error(session, 'Hello world!')
    ...

async def jinja_ctx_processor(rq: web.Request):
    session = await get_session(rq)
    return {"get_flashed_messages": lambda: session.pop("flash", [])}

app = web.Application()
app.add_routes([web.get('/', index)])
set_session(app, EncryptedCookieStorage('secret_key', cookie_name='session_app'))
set_jinja(app, loader=FileSystemLoader('templates_path'), context_processors=[jinja_ctx_processor])
web.run_app(app)

index.html

<html>
  {% for message, level in get_flashed_messages() %}
    <div class="alert alert-{{ level }} alert-dismissible fade show" role="alert">
      {{ message }}
      <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
    </div>
  {% endfor %}
</html>

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

7 participants