I receive an AttributeError: 'NoneType', webpy multiple sessions using beaker

143 Views Asked by At

I am building a webpy platform for my school to make posts and such for their graduation commencement. I've been writing this python code and I am unsure of what to do. I have tried using beaker to manage the multiple sessions, I based this code off of StuFish's code and seem to be unsure of how to synthesize my code with his code. I get an issue with rendering the home page.
Here is the code we have:

    import web
    import datetime
    from beaker.middleware import SessionMiddleware
    from Models import RegisterModel, LoginModel, Posts

    web.config.debug = False

    urls = (
            '/', 'Home',
            '/adminhome', 'AdminHome',
            '/modhome', 'ModHome',
            '/register', 'Register', 
            '/postreg', 'PostRegistration',
            '/login', 'Login',
            '/check-login', "CheckLogin",
            '/logout', 'Logout',
            '/post-activity', 'PostActivity',
            '/profile', 'Profile',
            '/settings', 'Settings',
            '/update-user', 'UpdateSettings',
            '/admin', 'Admin'
            )

    t_globals = {
                 'datestr': web.datestr,
                 'str': str,
                 'datetime': datetime
                 }

    app = web.application(urls, globals())

    session = web.session.Session(app, web.session.DiskStore("sessions"),initializer={"user":None})
    session_data = session._initializer

    render = web.template.render("Views/Templates", base="MainLayout", globals={"session":session_data, "current_user": session_data["user"]})

    # beaker options are optional.... but it's good to see 
    # where they are called

    session_opts = {
        'session.cookie_expires': True,
        'session.timeout' : 600,
        'session.secure' : True,
    }

    # define webPy app

    # smash it all together and define name for cookie key (sid)
    def session_mw(app):
        return SessionMiddleware(app, config = session_opts, key = "sid")



    # function to check if we are logged in
    def logged(session):
        if 'Login' in session:
            if session['Login']==1:
                return True
            else:
                return False
        else:
            return False

    # create different renders based on log in privilege
    def create_render(privilege):
        session = web.ctx.environ['beaker.session']
        if logged(session) == True:
            if privilege == 0:
                print("OH BABY")
                render = web.template.render('/Views/Templates/user/', base='/Views/Templates/MainLayout', globals=t_globals)
            elif privilege == 1:
                print("LET ME LOVE YOU")
                render = web.template.render('/Views/Templates/user/', base='/Views/Templates/MainLayout', globals=t_globals)
            elif privilege == 2:
                print("DONT HURT ME")          
                render = web.template.render('/Views/Templates/admin/', base='/Views/Templates/MainLayout', globals=t_globals)
            else:
                print("NOOT NOOT")          
                render = web.template.render('/Views/Templates/viewer', base='/Views/Templates/MainLayout', globals=t_globals)

            render = web.template.render('/Views/Templates/', base='MainLayout', globals=t_globals)
            return render

    class Login:
        def GET(self):
            session = web.ctx.environ['beaker.session']
            if logged(session) == True:
                print("SOMEBODY ONCE TOLD ME THAT THE WORLD WAS GONNA ROLL ME BUT I AINT THE SHARPEST TOOL IN THE SHED")
                render = create_render(session['privilege'])
                return render.Home()
            else:
                render = create_render(0)
                print("BLAH BLAH BLAH BLAH")
                return render.Home()

    # I get user credentials from a database (called in model.get_users) 
        def POST(self):
            session = web.ctx.environ['beaker.session']
            data= web.input()
            name = data['user']
            password = data['password']
            ident = model.get_users(m, name)
            try:
                if password == ident.password.strip():
                    session['Login'] = 1
                    session['privilege'] = ident['privilege']
                    session['user'] = name
                    session.save()
                    render = create_render(session['privilege'])
                    print("HERE")
                    return render.Home()

                else:
                    session.login = 0
                    session.privilege = 0
                    session.user = 'none'
                    render = create_render(session['privilege'])
                    print("NO HERE YO")
                    return render.Login()
            except:
                session['Login'] = 0
                session['privilege'] = 0
                render = create_render(session['privilege'])
                print("BANANA")
                return render.Login()

    # Credits go to bbangert for the middleware code
    class Logout:
        def GET(self):
            session = web.ctx.environ['beaker.session']    
            try:
                render = create_render(0)
                session.invalidate()
                session.delete()
                print("TOPSY TURVY")
                return render.Login()
            except:
                session.invalidate()
                session.delete()
                render = create_render(0)
                print("MESSY RIGHT")
                return render.Login()

    class Home:
        def GET(self):
            session = web.ctx.environ['beaker.session']
            if logged(session) == False:
                raise web.seeother('/login')
            else:
                render = create_render(0)
                return render.Home()

    '''
            data = type('obj', (object,), {'username':'q', 'password':'q'})
            login = LoginModel.LoginModel()
            isValid = login.check_user(data)
            if isValid:
              session_data['user'] = isValid

            post_model = Posts.Posts()
            posts = post_model.get_all_posts()

            return render.Home(posts)
    '''

    class Register:
        def GET(self):
          return render.Register()

    class PostRegistration:
        def POST(self):
          print("DOING POST PROCESSING")
          data = web.input()
          reg_model = RegisterModel.RegisterModel()
          reg_model.insert_user(data)
          return data.username

    class CheckLogin:
        def POST(self):
          print("DOING CHECK LOGIN")
          data = web.input()
          login = LoginModel.LoginModel()
          isValid = login.check_user(data)
          if isValid:
            session_data["user"] = isValid
            return isValid
          return "error"

    class PostActivity:
        def POST(self):
          print("DOING POST ACTIVITY")
          data = web.input()
          data.username = session_data['user']['username']
          post_model = Posts.Posts()
          post_model.insert_post(data)    
          return "success"

    class Profile:
        def GET(self):
          return render.Profile()

    class Settings:
        def GET(self):
          return render.Settings()

    class UpdateSettings:
        def POST(self):
          data = web.input()
          data.username = session_data['user']['username']
          update = RegisterModel.RegisterModel()
          update.update_settings(data)
          return "success"

    class Admin:
      def GET(self):
        return render.Admin()

    class AdminHome:
      def GET(self):
        return AdminHome()

    class ModHome:
      def GET(self):
        return ModHome()

    if __name__ == "__main__":
        app.run(session_mw)

I understand that I have defined render multiple times but that was the same case with this code so I don't understand why that would be a problem.

Here is the error message we receive:

    http://0.0.0.0:8080/
    BLAH BLAH BLAH BLAH
    Traceback (most recent call last):
      File "/usr/local/lib/python3.4/dist-packages/web/application.py", line 257, in process
        return self.handle()
      File "/usr/local/lib/python3.4/dist-packages/web/application.py", line 248, in handle
        return self._delegate(fn, self.fvars, args)
      File "/usr/local/lib/python3.4/dist-packages/web/application.py", line 488, in _delegate
        return handle_class(cls)
      File "/usr/local/lib/python3.4/dist-packages/web/application.py", line 466, in handle_class
        return tocall(*args)
      File "app.py", line 94, in GET
        return render.Home()
    AttributeError: 'NoneType' object has no attribute 'Home'

If anyone can give me a solution or help me solve this error, that would be greatly appreciates

sidenote: I am associated with this guy just in case if you thought that code was similiar

1

There are 1 best solutions below

2
busterroni On

If logged(session) is false when you call create_render(privilege), create_render(privilege) will return None. So, when render = create_render(0) runs two lines before your error, you are setting render to None. Then you try to render the page Home when render is None, which will raise an exception.

In create_render(privilege) you should consider the case where logged(session) is false.