使用 Python & Flask 实现 RESTful Web API
环境安装:
sudo pip install flask
Flask 是一个Python的微服务的框架,基于Werkzeug, 一个 WSGI 类库。
Flask 优点:
- Written in Python (that can be an advantage);
- Simple to use;
- Flexible;
- Multiple good deployment options;
- RESTful request dispatching
RESOURCES
一个响应 /articles 和 /articles/:id的 API 服务:
- from flask import Flask, url_for
- app = Flask(__name__)
- @app.route('/')
- def api_root():
- return 'Welcome'
- @app.route('/articles')
- def api_articles():
- return 'List of ' + url_for('api_articles')
- @app.route('/articles/<articleid>')
- def api_article(articleid):
- return 'You are reading ' + articleid
- if __name__ == '__main__':
- app.run()
请求:
curl http://127.0.0.1:5000/
响应:
GET /
Welcome
GET /articles
List of /articles
GET /articles/123
You are reading 123
REQUESTS
GET Parameters
- from flask import request
- @app.route('/hello')
- def api_hello():
- if 'name' in request.args:
- return 'Hello ' + request.args['name']
- else:
- return 'Hello John Doe'
请求:
GET /hello
Hello John Doe
GET /hello?name=Luis
Hello Luis
Request Methods (HTTP Verbs)
- @app.route('/echo', methods = ['GET', 'POST', 'PATCH', 'PUT', 'DELETE'])
- def api_echo():
- if request.method == 'GET':
- return "ECHO: GET\n"
- elif request.method == 'POST':
- return "ECHO: POST\n"
- elif request.method == 'PATCH':
- return "ECHO: PACTH\n"
- elif request.method == 'PUT':
- return "ECHO: PUT\n"
- elif request.method == 'DELETE':
- return "ECHO: DELETE"
请求指定request type:
curl -X PATCH http://127.0.0.1:5000/echo
GET /echo
ECHO: GET
POST /ECHO
ECHO: POST
Request Data & Headers
- from flask import json
- @app.route('/messages', methods = ['POST'])
- def api_message():
- if request.headers['Content-Type'] == 'text/plain':
- return "Text Message: " + request.data
- elif request.headers['Content-Type'] == 'application/json':
- return "JSON Message: " + json.dumps(request.json)
- elif request.headers['Content-Type'] == 'application/octet-stream':
- f = open('./binary', 'wb')
- f.write(request.data)
- f.close()
- return "Binary message written!"
- else:
- return "415 Unsupported Media Type ;)"
请求指定content type:
curl -H "Content-type: application/json" \
-X POST http://127.0.0.1:5000/messages -d '{"message":"Hello Data"}'
curl -H "Content-type: application/octet-stream" \
-X POST http://127.0.0.1:5000/messages --data-binary @message.bin
RESPONSES
- from flask import Response
- @app.route('/hello', methods = ['GET'])
- def api_hello():
- data = {
- 'hello' : 'world',
- 'number' : 3
- }
- js = json.dumps(data)
- resp = Response(js, status=200, mimetype='application/json')
- resp.headers['Link'] = 'http://luisrei.com'
- return resp
查看response HTTP headers:
curl -i http://127.0.0.1:5000/hello
优化代码:
from flask import jsonify
使用
- resp = jsonify(data)
- resp.status_code = 200
替换
- resp = Response(js, status=200, mimetype='application/json')
Status Codes & Errors
- @app.errorhandler(404)
- def not_found(error=None):
- message = {
- 'status': 404,
- 'message': 'Not Found: ' + request.url,
- }
- resp = jsonify(message)
- resp.status_code = 404
- return resp
- @app.route('/users/<userid>', methods = ['GET'])
- def api_users(userid):
- users = {'':'john', '':'steve', '':'bill'}
- if userid in users:
- return jsonify({userid:users[userid]})
- else:
- return not_found()
请求:
GET /users/2
HTTP/1.0 200 OK
{
"2": "steve"
}
GET /users/4
HTTP/1.0 404 NOT FOUND
{
"status": 404,
"message": "Not Found: http://127.0.0.1:5000/users/4"
}
AUTHORIZATION
- from functools import wraps
- def check_auth(username, password):
- return username == 'admin' and password == 'secret'
- def authenticate():
- message = {'message': "Authenticate."}
- resp = jsonify(message)
- resp.status_code = 401
- resp.headers['WWW-Authenticate'] = 'Basic realm="Example"'
- return resp
- def requires_auth(f):
- @wraps(f)
- def decorated(*args, **kwargs):
- auth = request.authorization
- if not auth:
- return authenticate()
- elif not check_auth(auth.username, auth.password):
- return authenticate()
- return f(*args, **kwargs)
- return decorated
replacing the check_auth
function and using the requires_auth
decorator:
- @app.route('/secrets')
- @requires_auth
- def api_hello():
- return "Shhh this is top secret spy stuff!"
HTTP basic authentication:
curl -v -u "admin:secret" http://127.0.0.1:5000/secrets
SIMPLE DEBUG & LOGGING
Debug:
app.run(debug=True)
Logging:
- import logging
- file_handler = logging.FileHandler('app.log')
- app.logger.addHandler(file_handler)
- app.logger.setLevel(logging.INFO)
- @app.route('/hello', methods = ['GET'])
- def api_hello():
- app.logger.info('informing')
- app.logger.warning('warning')
- app.logger.error('screaming bloody murder!')
- return "check your logs\n"
参考:
使用 Python & Flask 实现 RESTful Web API的更多相关文章
- 我所理解的RESTful Web API [Web标准篇]
REST不是一个标准,而是一种软件应用架构风格.基于SOAP的Web服务采用RPC架构,如果说RPC是一种面向操作的架构风格,而REST则是一种面向资源的架构风格.REST是目前业界更为推崇的构建新一 ...
- 我所理解的RESTful Web API [设计篇]
<我所理解的RESTful Web API [Web标准篇]>Web服务已经成为了异质系统之间的互联与集成的主要手段,在过去一段不短的时间里,Web服务几乎清一水地采用SOAP来构建.构建 ...
- 对RESTful Web API的理解与设计思路
距离上一篇关于Web API的文章(如何实现RESTful Web API的身份验证)有好些时间了,在那篇文章中提到的方法是非常简单而有效的,我在实际的项目中就这么用了,代码经过一段时间的磨合,已经很 ...
- About Restful Web Api Something.
这种轻量级的服务架构目前来说还是比较流行的,比如微信的公众平台的接口开发就是一个很好的案例,提到restful那么他到底是一个什么样的东西? REST(Representational State T ...
- 【ASP.NET MVC 学习笔记】- 19 REST和RESTful Web API
本文参考:http://www.cnblogs.com/willick/p/3441432.html 1.目前使用Web服务的三种主流的方式是:远程过程调用(RPC),面向服务架构(SOA)以及表征性 ...
- RESTful Web API 理解
REST 是一种应用架构风格,不是一种标准,是面向资源架构(ROA)风格,与具体技术平台无关,REST架构的应用未必建立在Web之上,与之对应的是传统的Web Service 采用的面向操作的RPC架 ...
- 个人学期总结及Python+Flask+MysqL的web建设技术过程
一个学期即将过去,我们也迎来了2018年.这个学期,首次接触了web网站开发建设,不仅是这门课程,还有另外一门用idea的gradle框架来制作网页. 很显然,用python语言的flask框架更加简 ...
- RESTful Web API 实践
REST 概念来源 网络应用程序,分为前端和后端两个部分.当前的发展趋势,就是前端设备层出不穷(手机.平板.桌面电脑.其他专用设备...). 因此,必须有一种统一的机制,方便不同的前端设备与后端进行通 ...
- Python+Flask+MysqL的web建设技术过程
一.前言(个人学期总结) 个人总结一下这学期对于Python+Flask+MysqL的web建设技术过程的学习体会,Flask小辣椒框架相对于其他框架而言,更加稳定,不会有莫名其妙的错误,容错性强,运 ...
随机推荐
- 等待与希望,.NET Core 的发展壮大
前几天微软推出了.net core 2.0, 尽管我现在使用的技术栈和微软已经没有一丝瓜葛, 但碰到微软放大招,心里还是瘙痒难当,忍不住偷偷摸摸的体验了一把. 谁叫我是通过微软系技术入的行呢,旧情难忘 ...
- 一个基于JRTPLIB的轻量级RTSP客户端(myRTSPClient)——实现篇:(四)用户接口层之处理SDP报文
当RTSP客户端向RTSP服务端发送DESCRIBE命令时,服务端理应当回复一条SDP报文. 该SDP报文中包含RTSP服务端的基本信息.所能提供的音视频媒体类型以及相应的负载能力,以下是一段SDP示 ...
- java集合判断
java开发中经常需要做集合判断,在这里mark一下,加强记忆 为空判断: null == applyList || applyList.size() ==0 非空判断: applyList != n ...
- vc++6.0修改字体
近期在使用vc++6.0写C程序 问题:vc++自带的字体不太好看 解决办法:修改注册表 1. win+r 运行 regedit 调出注册表编辑器 进入到目录 HKEY_CURRENT_USER\SO ...
- Windbg调试关键区(CriticalSection)死锁
一. 准备工作 这里一个有关键区锁死问题的程序,运行之后依次点击"CS锁死"按钮.右上角退出按钮,程序就会卡死.(图1) 对于眼下的这个问题,界面完全失去响应,这说明负责消息处理的 ...
- Sublime Text 2安装图解
Sublime Text 2安装图解.. ---------------- ---------------- ---------------- ---------------- ----------- ...
- HTTP常见状态码
1.100状态码 1xx:临时响应,表示临时相应并需要请求者继续操作的状态码 100 (继续) 请求者应当继续提出请求. 服务器返回此代码表示已收到请求的第一部分,正在等待其余部分. 101 ...
- 读书笔记--C陷阱与缺陷(一)
要参与C语言项目,于是作者只好重拾C语言(之前都是C++,还是C++方便). 看到大家都推荐看看 C陷阱与缺陷(C traps and pitfalls),于是好奇的开始了这本书的读书之旅. 决定将 ...
- spring学习笔记1
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAATQAAAEBCAIAAAB5VM7WAAAgAElEQVR4nOy9Z3gc13n3zZT3efPESZ
- javaScript 设计模式系列之三:代理模式
介绍 代理模式为其他对象提供一种代理以控制对这个对象的访问. 根据代理模式的使用目的不同,代理模式又可以分为多种类型: 远程代理(Remote Proxy) 虚拟代理(Virtual Proxy)如需 ...