forked from kele59/python-django-learning
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRESTfulAPI.py
More file actions
312 lines (237 loc) · 6.21 KB
/
RESTfulAPI.py
File metadata and controls
312 lines (237 loc) · 6.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
# coding:utf-8
# author:eycode
# 该文件用于提供测试接口
# Flask + API模块
# 在本代码案例中必须安装两个模块:
# flask模块:pip install flask
# http认证模块(flask-httpauth):pip install flask-httpauth
# 参考地址:
# RESTful API中文版:http://www.pythondoc.com/flask-mega-tutorial/index.html
# RESTful API快速入门:http://www.cnblogs.com/kaituorensheng/p/4645080.html
# RESTful API官方版本:http://flask-restless.readthedocs.io/en/stable/api.html
# Flask官方:http://www.pythondoc.com/flask-mega-tutorial/index.html
from flask import Flask, jsonify
# 简单版本:
# app = Flask(__name__)
# @app.route('/')
# def index():
# return "Hello Python"
# if __name__ == "__main__":
# app.run(debug=True)
# 或
# app.run(host='0.0.0.0',port=9000)
# 测试:打开浏览器输入:http://127.0.0.1:5000
# 返回结果:
# Hello Python
# 简单分析:
# 第9行:app是Flask的实例,它接收包或者模块的名字作为参数,但一般都是传递__name__。
# 让flask.helpers.get_root_path函数通过传入这个名字确定程序的根目录,以便获得静态文件和模板文件的目录
# 第11~13行:使用app.route装饰器会将URL和执行的视图函数的关系保存到app.url_map属性上。
# 处理URL和视图函数的关系的程序就是路由,这里的视图函数就是hello_world。
# 第16行:执行app.run就可以启动服务了。默认Flask只监听虚拟机的本地127.0.0.1这个地址,端口为5000。
# 而我们对虚拟机做的端口转发端口是9000,所以需要制定host和port参数,0.0.0.0表示监听所有地址,这样就可以在本机访问了。
# 服务器启动后,会调用werkzeug.serving.run_simple进入轮询,默认使用单进程单线程的werkzeug.serving.BaseWSGIServer处理请求,
# 实际上还是使用标准库BaseHTTPServer.HTTPServer,通过select.select做0.5秒的“while TRUE”的事件轮询。
# 当我们访问“http://127.0.0.1:9000/”,通过app.url_map找到注册的“/”这个URL模式,就找到了对应的hello_world函数执行,返回“hello world!”,状态码为200。
# 如果访问一个不存在的路径,如访问“http://127.0.0.1:9000/a”,Flask找不到对应的模式,就会向浏览器返回“Not Found”,状态码为404
# 构建一个简单的入口
# app = Flask(__name__)
# tasks = [
# {
# 'id':1,
# 'name':"eycode",
# 'age':23,
# 'sex':"男"
# },
# {
# 'id':2,
# 'name':"imay",
# 'age':1,
# 'sex':'女'
# }
# ]
# @app.route("/api/v1.0/tasks", methods=['GET'])
# def _tasks():
# return jsonify({'tasks':tasks})
# if __name__ == "__main__":
# app.run(host='0.0.0.0', port=9000, debug=True)
# 打开浏览器输入:http://127.0.0.1:9000/api/v1.0/tasks
# 返回结果:
# {
# "tasks": [
# {
# "age": 23,
# "id": 1,
# "name": "eycode",
# "sex": "\u7537"
# },
# {
# "age": 1,
# "id": 2,
# "name": "imay",
# "sex": "\u5973"
# }
# ]
# }
# GET方式递交参数,返回值
# from flask import abort, make_response
# app = Flask(__name__)
# tasks = [
# {
# 'id':1,
# 'name':"eycode",
# 'age':23,
# 'sex':"男"
# },
# {
# 'id':2,
# 'name':"imay",
# 'age':23,
# 'sex':"男"
# },
# {
# 'id':3,
# 'name':"benet",
# 'age':23,
# 'sex':"男"
# }
# ]
# @app.route('/api/v1.0/<int:task_id>', methods=['GET'])
# def get_tasks(task_id):
# # 当传进的id是多少就读取字典的哪个部分
# task = filter(lambda t:t['id'] == task_id, tasks)
# if len(task) == 0:
# """判断是否存在,如果不存在,则返回404页面"""
# abort(404)
# return jsonify({'task':task[0]})
# # 自定义404信息(以json的方式返回数据)
# @app.errorhandler(404)
# def not_found(error):
# return make_response(jsonify({'error': 'Not found'}), 404)
# if __name__ == "__main__":
# # 关闭调试
# app.run(debug=False)
# 测试:http://127.0.0.1:5000/api/v1.0/1
# 返回结果:
# {
# "task": {
# "age": 23,
# "id": 1,
# "name": "eycode",
# "sex": "\u7537"
# }
# }
# 测试: http://127.0.0.1:5000/api/v1.0/5
# 返回结果:
# {
# "error": "Not found"
# }
# 通过Post方式提交数据
# from flask import request
# app = Flask(__name__)
# tasks = [
# {
# 'id':1,
# 'name':"eycode",
# 'age':23,
# 'sex':"男"
# },
# {
# 'id':2,
# 'name':"imay",
# 'age':23,
# 'sex':"男"
# },
# {
# 'id':3,
# 'name':"benet",
# 'age':23,
# 'sex':"男"
# }
# ]
# @app.route('/api/v1.0/tasks', methods=['POST'])
# def create_task():
# if not request.json or not 'title' in request.json:
# abort(404)
# task = {
# 'id': tasks[-1]['id'] + 1,
# 'title': request.json['title'],
# 'sex': request.json.get('sex', ""),
# 'done': False
# }
# tasks.append(task)
# return jsonify({'task':task}), 201
# if __name__ == "__main__":
# app.run(debug=False)
# 测试:curl -i -H "Content-Type: application/json" -X POST -d '{"title":"Read a book"}' http://localhost:5000//api/v1.0/tasks
# 一些参数:
# -i :显示信息
# -H:指定http头
# -X:提交方式不区分大小写
# -d:字典
# API安全性使用
from flask.ext.httpauth import HTTPBasicAuth
from flask import abort, make_response
auth = HTTPBasicAuth()
@auth.get_password
def get_password(username):
if username == "eycode":
return 'python'
return None
@auth.error_handler
def unauthorized():
return make_response(jsonify({'error':'Unauthorized access'}), 403)
tasks = [
{
'id':1,
'name':"eycode",
'age':23,
'sex':"男"
},
{
'id':2,
'name':"imay",
'age':23,
'sex':"男"
},
{
'id':3,
'name':"benet",
'age':23,
'sex':"男"
}
]
app = Flask(__name__)
@app.route('/api/v1.0/tasks', methods=['GET'])
@auth.login_required
def get_tasks():
return jsonify({'tasks': tasks})
if __name__ == "__main__":
app.run()
# 测试:http://127.0.0.1:5000/api/v1.0/tasks
# 返回结果:
# {
# "error": "Unauthorized access"
#
# 测试:curl -u eycode:python -i http://localhost:5000/api/v1.0/tasks
# 一些参数:
# -u:用户名:密码
# 返回结果:
# {
# 'id':1,
# 'name':"eycode",
# 'age':23,
# 'sex':"男"
# },
# {
# 'id':2,
# 'name':"imay",
# 'age':23,
# 'sex':"男"
# },
# {
# 'id':3,
# 'name':"benet",
# 'age':23,
# 'sex':"男"
# }