Bottle micro web services framework 11 : forms get/post
List of Bottle Micro Web Services Tutorials
- Introduction
- Static files
- Template
- json
- Bucket List App I - sqlite, route, and template
- Bucket List App II - get & post
- Bucket List App III - Editing
- Bucket List App IV - route validation, regex, and static_file
- Bucket List App V - json
- json to html table
- Forms - Get & Post
- Forms - Get & Post with editable and checkbox table cells
Here is a description from HTML <form> method Attribute:
The method attribute specifies how to send form-data (the form-data is sent to the page specified in the action attribute). The form-data can be sent as URL variables (with method="get") or as HTTP post transaction (with method="post").
GET:
- Appends form-data into the URL in name/value pairs
- The length of a URL is limited (about 3000 characters)
- Never use GET to send sensitive data! (will be visible in the URL)
- Useful for form submissions where a user want to bookmark the result
- GET is better for non-secure data, like query strings in Google
POST:
- Appends form-data inside the body of the HTTP request (data is not shown is in URL)
- Has no size limitations
- Form submissions with POST cannot be bookmarked
Here is a sample:
disp.py:
from bottle import route, run, template HOST = '192.168.47.101' test = { 'protocol': ['protocol1','protocol2','protocol3'], 'service':['s1','s2','s3'], 'plugin': ['plug1','plug2','plug3'], 'result':[1,0,1] } number_of_test_cases = len(test['result']) @route('/page1') def serve_homepage(): return template('disp_table',rows = test, cases = number_of_test_cases) @route('/new') def add_new(): return template('add_case') run(host=HOST, port=8080, debug=True)
add_case.tpl:
<p>Add a new case to the list:</p> <form action="/new" method="GET"> protocol: <input type="text" size="50" maxlength="50" name="protocol"><br> service: <input type="text" size="50" maxlength="50" name="service"><br> plugin: <input type="text" size="50" maxlength="100" name="plugin"><br> <input type="submit" name="add" value="Add to the list"> </form>
As we can see from the picture below, upon submit, the form-data has been appended to the URL in name/value pairs: URL?name=value&name;=value:
disp_table.tpl:
%# disp_table.tpl <p>The items are as follows:</p> <table border="1"> <tr> %for r in rows: <th>{{r}}</th> %end </tr> %for i in range(cases): <tr> %for r in rows: <td>{{rows[r][i]}}</td> %end </tr> %end </table>
disp.py:
from bottle import route, run, template HOST = '192.168.47.101' test = { 'protocol': ['protocol1','protocol2','protocol3'], 'service':['s1','s2','s3'], 'plugin': ['plug1','plug2','plug3'], 'result':[1,0,1] } number_of_test_cases = len(test['result']) @route('/page1') def serve_homepage(): return template('disp_table',rows = test, cases = number_of_test_cases) @route('/new') def add_new(): return template('add_case_post') run(host=HOST, port=8080, debug=True)
disp_table.tpl:
%# disp_table.tpl <p>The items are as follows:</p> <table border="1"> <tr> %for r in rows: <th>{{r}}</th> %end </tr> %for i in range(cases): <tr> %for r in rows: <td>{{rows[r][i]}}</td> %end </tr> %end </table>
add_case_post.tpl:
<p>Add a new case to the list:</p> <form action="/new" method="POST"> protocol: <input type="text" size="50" maxlength="50" name="protocol"><br> service: <input type="text" size="50" maxlength="50" name="service"><br> plugin: <input type="text" size="50" maxlength="100" name="plugin"><br> <input type="submit" name="add" value="Add to the list"> </form>
Even though the error message, 'HTTP Error 405 Method not allowed', appears to be caused by not allowing ISPs the POST method or Cross-site request forgery(CSRF) which involve HTTP requests that have side effects (not idempotent). But we can make it work with the following code, though not in perfect form.
from bottle import route, run, template, request try: import simplejson as json except ImportError: import json HOST = '192.168.47.101' test_dic = { 'protocol': ['protocol1','protocol2','protocol3'], 'service':['s1','s2','s3'], 'plugin': ['plug1','plug2','plug3'], 'result':[1,0,1] } number_of_test_cases = len(test_dic['result']) @route('/page1') def serve_homepage(): return template('disp_table',rows = test_dic, cases = number_of_test_cases) @route('/new') def add_new(): return template('add_case_post') @route('/new', method='POST') def add_new(): p = request.forms.get('protocol') with open('test.json', 'w') as f: json.dump(test_dic, f) print 'p=',p run(host=HOST, port=8080, debug=True)
Note that we added additional route with POST and imported 'request'.
Ph.D. / Golden Gate Ave, San Francisco / Seoul National Univ / Carnegie Mellon / UC Berkeley / DevOps / Deep Learning / Visualization