Search code examples
python-3.xtornado

Tornado rediret incur TypeError: initialize() missing 1 required positional argument: 'url'


I am new to tornado and web service development, and currently implementing a tiny web for practising tornado module.

This is the python code I used for my server

import bcrypt
import concurrent.futures
#import MySQLdb
#import markdown
import os.path
import re
import subprocess
#import torndb
import tornado.escape
from tornado import gen
import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
import unicodedata
from tornado.options import define, options

define("port",default=8889,help='run on the given port',type=int)


class HomeHandler(tornado.web.RequestHandler):

    def get(self):
        #login here
        self.render('index.html')

    def post(self):
        def readcodebook(codebook):
            with open(codebook,'r+') as f:
                CodeLines=f.read().split('\n')
                combinations={}
                for c in CodeLines:
                    if len(c)>0:
                        combinations[c.split('\t')[0]]=c.split('\t')[1]
            return combinations
        UserFile='/home/john/PyServer/Users/codebook.txt'
        CodeBook=readcodebook(UserFile)

        if self.get_argument("login") in CodeBook.keys():
            if CodeBook[self.get_argument("login")]==self.get_argument("password"):
                #correct pwd
                self.redirect(self.get_argument("next","/display/"))
            else:
                #incorrect pwd
                self.render("index.html", error='incorrect password!')
                return
        else:
            #user not found
            self.render("index.html", error="account not found!")
            return


class DisplayHandler(tornado.web.RedirectHandler):
    def get(self):
        self.render("displaycontent.html")
    pass


class Application(tornado.web.Application):
    def __init__(self):
        handlers = [
            (r"/", HomeHandler),
            (r"/display/", DisplayHandler),
        ]
        settings = dict(
            #blog_title=u"Tornado Blog",
            template_path=os.path.join(os.path.dirname(__file__), "templates"),
            static_path=os.path.join(os.path.dirname(__file__), "static"),
            #ui_modules={"Entry": EntryModule},
            #xsrf_cookies=True,
            #cookie_secret="__TODO:_GENERATE_YOUR_OWN_RANDOM_VALUE_HERE__",
            #login_url="/auth/login",
            debug=True,
        )
        tornado.web.Application.__init__(self,handlers,**settings)

if __name__=="__main__":
    tornado.options.parse_command_line()
    http_server=tornado.httpserver.HTTPServer(Application())
    http_server.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()

and this is the index.html for user logon:

CSSFlow
Login Form
Previous
Next

    Twitter
    Facebook
    RSS
    Newsletter

<!DOCTYPE html>
<!--[if lt IE 7]> <html class="lt-ie9 lt-ie8 lt-ie7" lang="en"> <![endif]-->
<!--[if IE 7]> <html class="lt-ie9 lt-ie8" lang="en"> <![endif]-->
<!--[if IE 8]> <html class="lt-ie9" lang="en"> <![endif]-->
<!--[if gt IE 8]><!--> <html lang="en"> <!--<![endif]-->
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  <title>Login Form</title>
  <link rel="stylesheet" href="css/style.css">
  <!--[if lt IE 9]><script src="//html5shim.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
</head>
<body>
  <section class="container">
    <div class="login">
      <h1>Login to Web App</h1>
      <form method="post" action="/">
        <p><input type="text" name="login" value="" placeholder="Username or Email"></p>
        <p><input type="password" name="password" value="" placeholder="Password"></p>
        <p class="remember_me">
          <label>
            <input type="checkbox" name="remember_me" id="remember_me">
            Remember me on this computer
          </label>
        </p>
        <p class="submit"><input type="submit" name="commit" value="Login"></p>
      </form>
    </div>

    <div class="login-help">
      <p>Forgot your password? <a href="index.html">Click here to reset it</a>.</p>
    </div>
  </section>

  <section class="about">
    <p class="about-links">
      <a href="http://www.cssflow.com/snippets/login-form" target="_parent">View Article</a>
      <a href="http://www.cssflow.com/snippets/login-form.zip" target="_parent">Download</a>
    </p>
    <p class="about-author">
      &copy; 2012&ndash;2013 <a href="http://thibaut.me" target="_blank">Thibaut Courouble</a> -
      <a href="http://www.cssflow.com/mit-license" target="_blank">MIT License</a><br>
      Original PSD by <a href="http://www.premiumpixels.com/freebies/clean-simple-login-form-psd/" target="_blank">Orman Clark</a>
  </section>
</body>
</html>

    Live Demo
    HTML Source
    SCSS Source

    Tweet
    Share

    View Article
    Download
    Download All

90% Unlimited Downloads Choose from Over 300,000 Vectors, Graphics & Photos.ads via Carbon

The problem now is that tornado will throw an uncaught exception with description below and shows Error 404 not found in web browser, when I click submit button in index.html with correct username and password:

[E 170108 11:21:55 http1connection:54] Uncaught exception
    Traceback (most recent call last):
      File "/home/gaobo/anaconda3/lib/python3.5/site-packages/tornado/http1connection.py", line 238, in _read_message
        delegate.finish()
      File "/home/gaobo/anaconda3/lib/python3.5/site-packages/tornado/httpserver.py", line 289, in finish
        self.delegate.finish()
      File "/home/gaobo/anaconda3/lib/python3.5/site-packages/tornado/web.py", line 2022, in finish
        self.execute()
      File "/home/gaobo/anaconda3/lib/python3.5/site-packages/tornado/web.py", line 2042, in execute
        **self.handler_kwargs)
      File "/home/gaobo/anaconda3/lib/python3.5/site-packages/tornado/web.py", line 183, in __init__
        self.initialize(**kwargs)
    TypeError: initialize() missing 1 required positional argument: 'url'

Could anybody here point out a way to fix this problem? Thanks a lot!


Solution

  • Tornado offers you two ways to accomplish a redirection. One using the RedirectHandler and the other way using the redirect method of the RequestHandler.

    On your example above you mixed these two ways causing the error you get.

    On your example, since you use the second way (RequestHandler.redirect), to accomplish a redirection to the displaycontent.html on a successful login, you need to replace the parent class of the DisplayHandler to be the RequestHandler innstead of the RedirectHandler.

    eg.

    class DisplayHandler(tornado.web.RequestHandler):
        def get(self):
            self.render("displaycontent.html")
    

    Also the parameters of the redirect method should only be the url(or alias) you want to redirect to.

    eg.

    #correct pwd
    self.redirect("/display/")
    

    If you are interested in some more reading for the redirection follow this link.