Python Cherrypy: 500 ValueError: Page handlers MUST return bytes
Asked Answered
G

3

6

I'm getting the following error from my cherrypy script that is being generated by the submit module.

ValueError: Page handlers MUST return bytes. Use tools.encode if you wish to return unicode

I turned tool.encode on in my config but I'm still getting this error. I'm allowing users to upload content via the jQuery Form Plugin. Anythoughts as to why I'm getting this error?

Here is my cherrypy file:

class Root(object):    

@cherrypy.expose
def index(self)
    return open('/home/joestox/webapps/freelinreg_static/index.html')

@cherrypy.expose
def submit(self, myfile):

    cherrypy.session['myfile'] = myfile
    data_name = myfile.filename

    #Send back to JQuery with Ajax
    #Put in JSON form
    data_name= json.dumps(dict(title = data_name))
    cherrypy.response.headers['Content-Type'] = 'application/json'

    return data_name



cherrypy.config.update({
    'tools.staticdir.debug': True,
    'log.screen': True,
    'server.socket_host': '127.0.0.1',
    'server.socket_port': *****,
    'tools.sessions.on': True,
    'tools.encode.on': True,
    'tools.encode.encoding': 'utf-8',
})

config = {
}

cherrypy.tree.mount(Root(), '/', config=config)
cherrypy.engine.start()

HTML:

<!DOCTYPE html>
    <html>
        <head> 
            <script type='text/javascript' src='freelinreg_static/google.js'></script>
            <script type='text/javascript' src='freelinreg_static/frontend.js'></script>
            <script type='text/javascript' src='freelinreg_static/malsup.js'></script>
        </head>
        <body>

        <form id="dataform" action="submit" method="post" enctype="multipart/form-data">
            <input type="file" name="myfile" id="myFile"/>
            <input type="submit" id="data_submit" value="Continue"/>
        </form>                          

        </body>
    </html>

jQuery (frontend.js):

$(document).ready(function () {
    (function () {
        $('#dataform').ajaxForm({
            url: "submit",
            success: function (data) {
                var $a_var = data['title'];
                $('body').append($a_var);
            }
        });
        return false;
    })();
});
Gabble answered 26/11, 2013 at 10:57 Comment(0)
S
4

You need to rearrange global config update to happen after application mount:

config = {
}

cherrypy.tree.mount(Root(), '/', config=config)

cherrypy.config.update({
    'tools.staticdir.debug': True,
    'log.screen': True,
    'server.socket_host': '127.0.0.1',
    'server.socket_port': *****,
    'tools.sessions.on': True,
    'tools.encode.on': True,
    'tools.encode.encoding': 'utf-8'
})

cherrypy.engine.start()

Because you were calling config = {} after your config update command you were overriding the update settings for Root application.

Also, change your submit function to this:

@cherrypy.expose
@cherrypy.tools.json_out
def submit(self, myfile):
    cherrypy.session['myfile'] = myfile

    # Return dict, which will be autoconverted to JSON
    # by the json_out tool (see decorator above)
    return {'title': myfile.filename}
Selector answered 26/11, 2013 at 13:41 Comment(4)
Thanks for the tip! Makes a lot of sense! Unfortunately I'm still getting the same 500 ValueError.Gabble
It worked! Anyways to send the data back to jQuery as a JSON dict still? Now the jQuery doesn't seem to realize that its a JSON dict.Gabble
Yes, you should use... JSONobj = JSON.parse(data); alert(JSONobj.title);Selector
To return json from dict use json_out toolPentlandite
S
9

I my case the issue started after switching from python2 to python3.

It was resolved by setting

    'tools.encode.text_only': False

In the app global configuration.

Hope it helps

Stanza answered 7/3, 2019 at 8:47 Comment(1)
After looking at the other answers this is what worked for me. Thank you.Almondeyed
P
5

Hi people looking for answers. I had the same problem but in my case this little addition solved everything.

return <some-json>.encode('utf8')
Preter answered 13/7, 2018 at 8:31 Comment(3)
Use json_out tool instead and just return a dictPentlandite
@webKnjaZ well fixed my problem, I had the same error and these two words fixed it so I was happyPreter
Yes, it's just not the best way to go architecturally.Pentlandite
S
4

You need to rearrange global config update to happen after application mount:

config = {
}

cherrypy.tree.mount(Root(), '/', config=config)

cherrypy.config.update({
    'tools.staticdir.debug': True,
    'log.screen': True,
    'server.socket_host': '127.0.0.1',
    'server.socket_port': *****,
    'tools.sessions.on': True,
    'tools.encode.on': True,
    'tools.encode.encoding': 'utf-8'
})

cherrypy.engine.start()

Because you were calling config = {} after your config update command you were overriding the update settings for Root application.

Also, change your submit function to this:

@cherrypy.expose
@cherrypy.tools.json_out
def submit(self, myfile):
    cherrypy.session['myfile'] = myfile

    # Return dict, which will be autoconverted to JSON
    # by the json_out tool (see decorator above)
    return {'title': myfile.filename}
Selector answered 26/11, 2013 at 13:41 Comment(4)
Thanks for the tip! Makes a lot of sense! Unfortunately I'm still getting the same 500 ValueError.Gabble
It worked! Anyways to send the data back to jQuery as a JSON dict still? Now the jQuery doesn't seem to realize that its a JSON dict.Gabble
Yes, you should use... JSONobj = JSON.parse(data); alert(JSONobj.title);Selector
To return json from dict use json_out toolPentlandite

© 2022 - 2024 — McMap. All rights reserved.