Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Python Flask Basics Character Builder Forms

Matt Russell
Matt Russell
5,810 Points

Generating form data from python

I wanted to understand how the html form was constructing the data to send to my flask server, so I attempted to send the form data directly from python. However, I could not replicate what the html form was doing. Does anyone know what I am doing wrong?

First, I added this line to the "save" function:

print "Request form: {}".format(request.form)

When submitting a name from the index website, that line prints this:

Request form: ImmutableMultiDict([('name', u'Name-from-website-form')])

Then I ran this very small python program:

---------------------------------
import json
import urllib2
url="http://0.0.0.0:8000/save"
data = { 'name': 'name-from-python' }
req = urllib2.Request(url)
urllib2.urlopen(req, json.dumps(data)).read()
---------------------------------

When running this, the print line from my flask server showed this:

Request form: ImmutableMultiDict([('{"name": "name-from-python"}', u'')])

In case it's not clear, the dictionary is a mapping from '{"name": "name-from-python"}' to an empty string -- clearly not what I intended.

What am I doing wrong?

[MOD: added ```python formating -cf]

Matt Russell
Matt Russell
5,810 Points

Sorry, the formatting of the pasted python program seems wrong. Trying again:

import json
import urllib2
url="http://0.0.0.0:8000/save"
data = { 'name': 'name-from-python' }
req = urllib2.Request(url)
urllib2.urlopen(req, json.dumps(data)).read()

1 Answer

Chris Freeman
MOD
Chris Freeman
Treehouse Moderator 68,454 Points

Hi Matt,

First, are you using Python 2? The urllib2 module was replaced in Python 3 with urllib.request and urllib.error.

Working wth Python2, I was able to get the following code to work (I modified to use my port 8080, and route to formdata for my setup):

# post data to flask server
import urllib
import urllib2
url="http://0.0.0.0:8080/formdata"
data = urllib.urlencode({'name' : 'name-from-python'})
content = urllib2.urlopen(url=url, data=data).read()

You can optionally add print(content)

formdata route:

# added to app.py: 
from flask import request

@app.route('/formdata', methods=('GET', 'POST'))
def formdata():
    try:
        print(request.form)
    except:
        print("formdata: no form")
    return redirect(url_for('index'))

Running python app.py in one window and running the "post data to flask server" code above in Python 2 shell in another window, produced the following from the flask app:

ImmutableMultiDict([('name', 'name-from-python')])
127.0.0.1 - - [17/Oct/2015 23:27:42] "POST /formdata HTTP/1.1" 302 -
127.0.0.1 - - [17/Oct/2015 23:27:42] "GET / HTTP/1.1" 200 -

If you want more introspection, you could add print(dir(request)) or print(dir(request.form)) to your save route to drill down into the posted request content.

Also, I found these StackOverflow posts helpful: making a post call instead of get using urllib2 and python urllib urllib2 post