Flask: Difference between revisions
From charlesreid1
| Line 28: | Line 28: | ||
now we run it with <code>python run.py</code> | now we run it with <code>python run.py</code> | ||
==Return Some Data== | ==Return Some Data with JSON== | ||
Now let's return some data from the RESTful server to the client (perhaps a sensor on a Raspberry Pi running the RESTful API): | Now let's return some data from the RESTful server to the client (perhaps a sensor on a Raspberry Pi running the RESTful API): | ||
| Line 85: | Line 85: | ||
} | } | ||
] | ] | ||
} | |||
</pre> | |||
==Send Some Data with POST== | |||
You can also send some data with POST requests: | |||
<source lang="python"> | |||
from flask import request | |||
@app.route('/todo/api/v1.0/tasks', methods=['POST']) | |||
def create_task(): | |||
if not request.json or not 'title' in request.json: | |||
abort(400) | |||
task = { | |||
'id': tasks[-1]['id'] + 1, | |||
'title': request.json['title'], | |||
'description': request.json.get('description', ""), | |||
'done': False | |||
} | |||
tasks.append(task) | |||
return jsonify({'task': task}), 201 | |||
</source> | |||
and the corresponding output when we POST data to the server: | |||
<pre> | |||
$ curl -i -H "Content-Type: application/json" -X POST -d '{"title":"Read a book"}' http://localhost:5000/todo/api/v1.0/tasks | |||
HTTP/1.0 201 Created | |||
Content-Type: application/json | |||
Content-Length: 104 | |||
Server: Werkzeug/0.8.3 Python/2.7.3 | |||
Date: Mon, 20 May 2013 05:56:21 GMT | |||
{ | |||
"task": { | |||
"description": "", | |||
"done": false, | |||
"id": 3, | |||
"title": "Read a book" | |||
} | |||
} | } | ||
</pre> | </pre> | ||
Revision as of 23:45, 30 July 2015
Basics
Flask 101
The Flask mega tutorial is really handy: http://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-i-hello-world
RESTful API
We can use Flask to design and implement a RESTful API service. Flask will be a server and interpret between URLs and Python actions. Note that this is particularly handy if you're designing an internet-of-things thing, as you can install Flask on a RaspberryPi, and now you have a RESTful API for accessing your Raspberry Pi! If you take it a step further, you can control the GPIO pins on the Raspberry Pi, and make the Pi do things with your hardware and circuitry based on your API actions.
Hello World
Let's put our Flask hello world app in run.py:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return "Hello, World!"
if __name__ == '__main__':
app.run(debug=True)
now we run it with python run.py
Return Some Data with JSON
Now let's return some data from the RESTful server to the client (perhaps a sensor on a Raspberry Pi running the RESTful API):
from flask import Flask, jsonify
app = Flask(__name__)
tasks = [
{
'id': 1,
'title': u'Buy groceries',
'description': u'Milk, Cheese, Pizza, Fruit, Tylenol',
'done': False
},
{
'id': 2,
'title': u'Learn Python',
'description': u'Need to find a good Python tutorial on the web',
'done': False
}
]
@app.route('/todo/api/v1.0/tasks', methods=['GET'])
def get_tasks():
return jsonify({'tasks': tasks})
if __name__ == '__main__':
app.run(debug=True)
Now you can request that resource using CURL:
$ $ curl -i http://localhost:5000/todo/api/v1.0/tasks
HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 294
Server: Werkzeug/0.8.3 Python/2.7.3
Date: Mon, 20 May 2013 04:53:53 GMT
{
"tasks": [
{
"description": "Milk, Cheese, Pizza, Fruit, Tylenol",
"done": false,
"id": 1,
"title": "Buy groceries"
},
{
"description": "Need to find a good Python tutorial on the web",
"done": false,
"id": 2,
"title": "Learn Python"
}
]
}
Send Some Data with POST
You can also send some data with POST requests:
from flask import request
@app.route('/todo/api/v1.0/tasks', methods=['POST'])
def create_task():
if not request.json or not 'title' in request.json:
abort(400)
task = {
'id': tasks[-1]['id'] + 1,
'title': request.json['title'],
'description': request.json.get('description', ""),
'done': False
}
tasks.append(task)
return jsonify({'task': task}), 201
and the corresponding output when we POST data to the server:
$ curl -i -H "Content-Type: application/json" -X POST -d '{"title":"Read a book"}' http://localhost:5000/todo/api/v1.0/tasks
HTTP/1.0 201 Created
Content-Type: application/json
Content-Length: 104
Server: Werkzeug/0.8.3 Python/2.7.3
Date: Mon, 20 May 2013 05:56:21 GMT
{
"task": {
"description": "",
"done": false,
"id": 3,
"title": "Read a book"
}
}
Packaging Flask Apps
Deploying Flask Web App as Submodule
Instructions for deploying a Flask web app as a submodule in a Python module:
First, your directory structure will look something like this:
README.md
setup.py
mymodule/
__init__.py
submodule1/
submodule2/
webapp/
__init__.py
additional_routes.py
templates/
[...]
static/
[...]
Next, your setup.py file will look something like this:
config = {
'description': 'My Module',
'install_requires': ['flask'],
'packages': ['mymodule','mymodule.submodule1','mymodule.submodule2','mymodule.webapp'],
'include_package_data' : True,
'package_data' : {
'templates' : 'mymodule/webapp/templates/*',
'static' : 'mymodule/webapp/static/*'
},
'scripts': [],
'name': 'mulch',
'zip_safe' : False
}
setup(**config)
The key lines here are include_package_data and package_data, which will also install your non-Python template and static files with your module.
Now you can install your module with python setup.py install, and your module is available to use from anywhere.
To create an instance of your module's web app from anywhere, follow these steps:
1. Install the module
2. Import the webapp submodule:
from mymodule.webapp import *
3. Start the webapp:
app.run(debug=True)
Voila!
More information: http://www.plankandwhittle.com/packaging-a-flask-web-app/
Yet more information: http://flask.pocoo.org/docs/patterns/distribute/