Bottle.py session with Beaker

杀马特。学长 韩版系。学妹 提交于 2019-11-30 11:41:39

问题


first time questioner here.

I'm currently struggling on how to use Beaker properly using the Bottle micro-framework. Here's the problematic program:

#!/usr/bin/python
# -*- coding: utf-8 -*-
# filename: server.py

import bottle as app
from beaker.middleware import SessionMiddleware

session_options = {
    'session.type': 'file',
    'session.data_dir': './session/',
    'session.auto': True,
}
app_middlware = SessionMiddleware(app.app(), session_options)
app_session = app.request.environ.get('beaker.session')

@app.route('/login')
def login():
    app_session = app.request.environ.get('beaker.session')
    app_session['logged_in'] = True

@app.route('/logout')
def logout():
    app_session = app.request.environ.get('beaker.session')
    if app_session.get('logged_in'):
        app_session['logged_in'] = False
        return 'You are logged out'
    app.redirect('/login')

@app.route('/dashboard')
def dashboard():
    app_session = app.request.environ.get('beaker.session')
    if app_session.get('logged_in'):
        return 'You are logged in'
    app.redirect('/login')

app.debug(True)
app.run(app=app_middlware, reloader=True)

If you noticed, I keep on calling app_session = app.request.environ.get('beaker.session') on every def block so just it will not return an error like: TypeError: 'NoneType' object does not support item assignment --- it seems that Python doesn't recognize variables that is outside its function (correct me if I'm wrong).

And here are the questions:

  1. What should I do to only have one instance of app_session = app.request.environ.get('beaker.session') so it can be available to every def blocks (I really need one instance since it's the same session to be checked and used).
  2. If this is the only way (it's ugly though), then should I just combine all routes that requires a session just so I can achieve the single instance of app_session?

Something like:

@app.route('/<path:re:(login|dashboard|logout)\/?>')
def url(path):
    app_session = app.request.environ.get('beaker.session')
    if 'login' in path:
        app_session['logged_in'] = True
    elif 'logout' in path:
        if app_session.get('logged_in'):
            # app_session.delete() it doesn't seem to work?
            app_session['logged_in'] = False
            return 'You are logged out'
        app.redirect('/login')
    elif 'dashboard' in path:
        if app_session.get('logged_in'):
            return 'You are logged in'
        app.redirect('/login')

回答1:


Using beaker in your bottle application is easy. First, set up your Bottle app:

import bottle
from bottle import request, route, hook
import beaker.middleware

session_opts = {
    'session.type': 'file',
    'session.data_dir': './session/',
    'session.auto': True,
}

app = beaker.middleware.SessionMiddleware(bottle.app(), session_opts)

And later on:

bottle.run(app=app)

With this in place, every time you receive a request, your Beaker session will be available as request.environ['beaker_session']. I usually do something like this for convenience:

@hook('before_request')
def setup_request():
    request.session = request.environ['beaker.session']

This arranges to run setup_request before handling any request; we're using the bottle.request variable (see the earlier import statement), which is a thread-local variable with information about the current request. From this point on, I can just refer to request.session whenever I need it, e.g.:

@route('/')
def index():
    if 'something' in request.session:
       return 'It worked!'

    request.session['something'] = 1


来源:https://stackoverflow.com/questions/13735333/bottle-py-session-with-beaker

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!