文章目录
需求
在双十一买了阿里云云小蜜的培训课程,花了几天学了一下,不过考了两次都没有考过,但是能够熟练使用云小蜜来搭建业务了,为了整合一些外部数据,例如天气,交通,电影啥的,需要封装处理一下第三方API或者调用自己的数据库。最后的需求就是变成RESTFUL API了,可以把这个请求地址直接放到云小蜜里边。
什么叫restful
REST的名称"表现层状态转化"中,省略了主语。“表现层"其实指的是"资源”(Resources)的"表现层"。
所谓"资源",就是网络上的一个实体,或者说是网络上的一个具体信息。它可以是一段文本、一张图片、一首歌曲、一种服务,总之就是一个具体的实在。你可以用一个URI(统一资源定位符)指向它,每种资源对应一个特定的URI。要获取这个资源,访问它的URI就可以,因此URI就成了每一个资源的地址或独一无二的识别符。
客户端用到的手段,只能是HTTP协议。具体来说,就是HTTP协议里面,四个表示操作方式的动词:GET、POST、PUT、DELETE。它们分别对应四种基本操作:GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源。
- GET /tickets # 获取ticket列表
- GET /tickets/12 # 查看某个具体的ticket
- POST /tickets # 新建一个ticket
- PUT /tickets/12 # 更新ticket 12.
- DELETE /tickets/12 #删除ticekt 12
代码
# -*- coding:utf-8 -*-
import os
from flask import Flask, abort
from flask_restful import reqparse, abort, Api, Resource
from flask_restful import fields, marshal
from resources import weather_info
app = Flask(__name__)
api = Api(app)
tasks = [
{
'todo_id': 1,
'title': u'Buy groceries',
'description': u'Milk, Cheese, Pizza, Fruit, Tylenol',
'done': False
},
{
'todo_id': 2,
'title': u'Learn Python',
'description': u'Need to find a good Python tutorial on the web',
'done': False
}
]
task_fields = {
'title': fields.String,
'description': fields.String,
'done': fields.Boolean,
'uri': fields.Url('task')
}
def abort_if_todo_doesnt_exist(todo_id):
"""
如果数据库(内存)中没有存储 todo_id 标识的数据 返回404 否则返回该条数据
:param todo_id: 标识id
:return: todo_id 标识的数据
"""
task = filter(lambda t: t['todo_id'] == todo_id, tasks)
if len(task) == 0:
abort(404, message="Todo {todo_id} doesn't exist".format(todo_id=todo_id))
else:
return task[0]
class Task(Resource):
def __init__(self):
# 使用 RequestParser来 解析传进来的参数
self.reqparse = reqparse.RequestParser()
self.reqparse.add_argument('title', type=str, location='json')
self.reqparse.add_argument('description', type=str, location='json')
self.reqparse.add_argument('done', type=bool, location='json')
super(Task, self).__init__()
def get(self, todo_id):
task = abort_if_todo_doesnt_exist(todo_id)
# 使用 marshal 按照 task_fields的定义来包装task
return marshal(task, task_fields), 201
def delete(self, todo_id):
task = abort_if_todo_doesnt_exist(todo_id)
tasks.remove(task)
# del task
return marshal(tasks, task_fields), 204
def put(self, todo_id):
new_task = abort_if_todo_doesnt_exist(todo_id)
args = self.reqparse.parse_args()
print(args)
for k, v in args.iteritems():
if v is not None:
new_task[k] = v
print(new_task)
return marshal(new_task, task_fields), 201
class TaskList(Resource):
def __init__(self):
self.reqparse = reqparse.RequestParser()
self.reqparse.add_argument('todo_id', type=int, required=True,
help='No todo id provided', location='json')
self.reqparse.add_argument('title', type=str, required=True,
help='No task title provided', location=['json'])
self.reqparse.add_argument('description', type=str, default="", location='json')
self.reqparse.add_argument('done', type=bool, default=False, location='json')
super(TaskList, self).__init__()
def get(self):
return marshal(tasks, task_fields), 201
def post(self):
args = self.reqparse.parse_args()
new_task = {}
for k, v in args.iteritems():
if v is not None:
new_task[k] = v
tasks.append(new_task)
return marshal(new_task, task_fields), 202
class Index(Resource):
def get(self):
weinfo = weather_info.getWeatherInfo("beijing")
return {"result": weinfo}, 200
class WeatherInfo(Resource):
def __init__(self):
self.reqparse = reqparse.RequestParser()
self.reqparse.add_argument("city", required=True,
help='No city provided')
def post(self):
args = self.reqparse.parse_args()
print(args)
weinfo = weather_info.getWeatherInfo(args['city'])
return {"result": weinfo}, 200
# 添加RESTFUL API的 解析路径
api.add_resource(TaskList, '/todo/api/v1.0/tasks', endpoint='tasks')
# <int:todo_id> todo_id 要能对应到解析函数的变量名称
api.add_resource(Task, '/todo/api/v1.0/tasks/<int:todo_id>', endpoint='task')
api.add_resource(Index, '/', endpoint='index')
#
api.add_resource(WeatherInfo, '/weather', endpoint='weather')
if __name__ == '__main__':
# 运行API接口程序 可以指定端口及 host
app.run(host='0.0.0.0', port=8889, debug=True)
参考资料
http://www.pythondoc.com/Flask-RESTful/quickstart.html
https://flask-restful.readthedocs.io/en/latest/
http://www.pythondoc.com/flask-restful/third.html
https://jiayi.space/post/ji-yu-flaskde-restful-apihou-duan-bi-ji
https://www.cnblogs.com/binlin1987/p/6971808.html