唉,最近熬夜看动漫,早上还测了个蛋疼的数学测验,我也是醉了,今天得早点睡。
实验目的:在flask应用中使用多个http头并借助PUT,POST提交数据
源代码:
__author__ = 'hochikong' from flask import Flask,request from flask.ext.restful import Resource,Api,reqparse app = Flask(__name__) api = Api(app) todos = {'task':'get the list of docker'} parser = reqparse.RequestParser() parser.add_argument('name',type=str,help='get the name') parser.add_argument('auth-token',type=str,help='put the token here',location='headers') class TodoSimple(Resource): def get(self,todo_id): args = parser.parse_args() if args['auth-token'] == 'thisismytoken': return {todo_id:todos[todo_id]} else: return {'error':'token error'},401 def put(self,todo_id): args = parser.parse_args() if args['auth-token'] == 'thisismytoken': todos[todo_id] = request.json.get('data') return todos,201 else: return {'status':'error'},401 class GetName(Resource): def post(self): args = parser.parse_args() name = args['name'] #name = {} #name['ac'] = args['name'] #name = request.json.get('name') return {'yourame':name} api.add_resource(TodoSimple,'/todo/<string:todo_id>') api.add_resource(GetName,'/getname') if __name__ == '__main__': app.run(debug=True)
测试的核心是TodoSimple类,测试的是PUT方法
测试工具由单纯的curl换成了firefox的REST client(话说,直接用curl我也真没什么耐心去用),安装firefox扩展参考此:http://www.blogjava.net/paulwong/archive/2014/04/19/412688.html
设计要求:要在HTTP请求中,包含content-type:application/json和自定义的auth-token头,另外请求体是一个json文档,flask应用应该懂得处理其中的数据
代码分析:
class TodoSimple(Resource): def get(self,todo_id): args = parser.parse_args() if args['auth-token'] == 'thisismytoken': return {todo_id:todos[todo_id]} else: return {'error':'token error'},401 def put(self,todo_id): args = parser.parse_args() if args['auth-token'] == 'thisismytoken': todos[todo_id] = request.json.get('data') return todos,201 else: return {'status':'error'},401
从我前一篇blog中,我知道可以用reqparse解析json数据,在TodoSimple类中,解析auth-token头是使用reqparse进行的,但我们要在前面定义该参数:
parser.add_argument('auth-token',type=str,help='put the token here',location='headers')
如果我们不使用reqparse解析,我们可以用flask自带的request模块解析:
todos[todo_id] = request.json.get('data')
而我的请求是这样的:
在这个工具中,Body不用再像在curl中那样在花括号外还要加引号,定义http头也方便多了。
通过request.json.get(),flask应用就可以解析多个http头和json数据了。
对应的curl请求为:
hochikong@hochikong-P41T-D3:~$ curl -i -X PUT -H 'Content-Type:application/json' -H 'auth-token:thisismytoken' -d '{"data":"hello world"}' http://localhost:5000/todo/abc HTTP/1.0 201 CREATED Content-Type: application/json Content-Length: 68 Server: Werkzeug/0.10.1 Python/2.7.6 Date: Sat, 18 Apr 2015 15:10:46 GMT { "abc": "hello world", "task": "get the list of docker" }
好,这次实验基本成功,下一步就是把各种资源分布在不同的python文件中,组织好代码的放置
研究过程中遇到的坑:
启用debug=True后,启动flask应用,提示错误:
ImportError: No module named _winreg
后来参考这位仁兄的文章修改了six.py(http://www.cnblogs.com/lvzwq/p/4267850.html),
改成这样:
if attr in ("__file__", "__name__") and self.mod not in sys.modules: # raise AttributeError raise AttributeError(attr) try: _module = self._resolve() except ImportError: raise AttributeError(attr) # _module = self._resolve() value = getattr(_module, attr) setattr(self, attr, value) return value
于是就没问题了,这是一个bug