环境安装:

  1. 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 服务:

  1. from flask import Flask, url_for
  2. app = Flask(__name__)
  3.  
  4. @app.route('/')
  5. def api_root():
  6. return 'Welcome'
  7.  
  8. @app.route('/articles')
  9. def api_articles():
  10. return 'List of ' + url_for('api_articles')
  11.  
  12. @app.route('/articles/<articleid>')
  13. def api_article(articleid):
  14. return 'You are reading ' + articleid
  15.  
  16. if __name__ == '__main__':
  17. app.run()

请求:

  1. curl http://127.0.0.1:5000/

响应:

  1. GET /
  2. Welcome
  3. GET /articles
  4. List of /articles
  5. GET /articles/123
  6. You are reading 123

REQUESTS

GET Parameters
  1. from flask import request
  2.  
  3. @app.route('/hello')
  4. def api_hello():
  5. if 'name' in request.args:
  6. return 'Hello ' + request.args['name']
  7. else:
  8. return 'Hello John Doe'

请求:

  1. GET /hello
  2. Hello John Doe
  3. GET /hello?name=Luis
  4. Hello Luis
Request Methods (HTTP Verbs)
  1. @app.route('/echo', methods = ['GET', 'POST', 'PATCH', 'PUT', 'DELETE'])
  2. def api_echo():
  3. if request.method == 'GET':
  4. return "ECHO: GET\n"
  5.  
  6. elif request.method == 'POST':
  7. return "ECHO: POST\n"
  8.  
  9. elif request.method == 'PATCH':
  10. return "ECHO: PACTH\n"
  11.  
  12. elif request.method == 'PUT':
  13. return "ECHO: PUT\n"
  14.  
  15. elif request.method == 'DELETE':
  16. return "ECHO: DELETE"

请求指定request type:

  1. curl -X PATCH http://127.0.0.1:5000/echo
  1. GET /echo
  2. ECHO: GET
  3. POST /ECHO
  4. ECHO: POST
Request Data & Headers
  1. from flask import json
  2.  
  3. @app.route('/messages', methods = ['POST'])
  4. def api_message():
  5.  
  6. if request.headers['Content-Type'] == 'text/plain':
  7. return "Text Message: " + request.data
  8.  
  9. elif request.headers['Content-Type'] == 'application/json':
  10. return "JSON Message: " + json.dumps(request.json)
  11.  
  12. elif request.headers['Content-Type'] == 'application/octet-stream':
  13. f = open('./binary', 'wb')
  14. f.write(request.data)
  15. f.close()
  16. return "Binary message written!"
  17.  
  18. else:
  19. return "415 Unsupported Media Type ;)"

请求指定content type:

  1. curl -H "Content-type: application/json" \
  2. -X POST http://127.0.0.1:5000/messages -d '{"message":"Hello Data"}'
  1. curl -H "Content-type: application/octet-stream" \
  2. -X POST http://127.0.0.1:5000/messages --data-binary @message.bin

RESPONSES

  1. from flask import Response
  2.  
  3. @app.route('/hello', methods = ['GET'])
  4. def api_hello():
  5. data = {
  6. 'hello' : 'world',
  7. 'number' : 3
  8. }
  9. js = json.dumps(data)
  10.  
  11. resp = Response(js, status=200, mimetype='application/json')
  12. resp.headers['Link'] = 'http://luisrei.com'
  13.  
  14. return resp

查看response HTTP headers:

  1. curl -i http://127.0.0.1:5000/hello

优化代码:

  1. from flask import jsonify

使用

  1. resp = jsonify(data)
  2. resp.status_code = 200

替换

  1. resp = Response(js, status=200, mimetype='application/json')

Status Codes & Errors

  1. @app.errorhandler(404)
  2. def not_found(error=None):
  3. message = {
  4. 'status': 404,
  5. 'message': 'Not Found: ' + request.url,
  6. }
  7. resp = jsonify(message)
  8. resp.status_code = 404
  9.  
  10. return resp
  11.  
  12. @app.route('/users/<userid>', methods = ['GET'])
  13. def api_users(userid):
  14. users = {'':'john', '':'steve', '':'bill'}
  15.  
  16. if userid in users:
  17. return jsonify({userid:users[userid]})
  18. else:
  19. return not_found()

请求:

  1. GET /users/2
  2. HTTP/1.0 200 OK
  3. {
  4. "2": "steve"
  5. }
  6. GET /users/4
  7. HTTP/1.0 404 NOT FOUND
  8. {
  9. "status": 404,
  10. "message": "Not Found: http://127.0.0.1:5000/users/4"
  11. }

AUTHORIZATION

  1. from functools import wraps
  2.  
  3. def check_auth(username, password):
  4. return username == 'admin' and password == 'secret'
  5.  
  6. def authenticate():
  7. message = {'message': "Authenticate."}
  8. resp = jsonify(message)
  9.  
  10. resp.status_code = 401
  11. resp.headers['WWW-Authenticate'] = 'Basic realm="Example"'
  12.  
  13. return resp
  14.  
  15. def requires_auth(f):
  16. @wraps(f)
  17. def decorated(*args, **kwargs):
  18. auth = request.authorization
  19. if not auth:
  20. return authenticate()
  21.  
  22. elif not check_auth(auth.username, auth.password):
  23. return authenticate()
  24. return f(*args, **kwargs)
  25.  
  26. return decorated

replacing the check_auth function and using the requires_auth decorator:

  1. @app.route('/secrets')
  2. @requires_auth
  3. def api_hello():
  4. return "Shhh this is top secret spy stuff!"

HTTP basic authentication:

  1. curl -v -u "admin:secret" http://127.0.0.1:5000/secrets

SIMPLE DEBUG & LOGGING

Debug:

  1. app.run(debug=True)

Logging:

  1. import logging
  2. file_handler = logging.FileHandler('app.log')
  3. app.logger.addHandler(file_handler)
  4. app.logger.setLevel(logging.INFO)
  5.  
  6. @app.route('/hello', methods = ['GET'])
  7. def api_hello():
  8. app.logger.info('informing')
  9. app.logger.warning('warning')
  10. app.logger.error('screaming bloody murder!')
  11.  
  12. return "check your logs\n"

参考:

Flask documentation

Flask snippets

Werkzeug documentation

curl manual

使用 Python & Flask 实现 RESTful Web API的更多相关文章

  1. 我所理解的RESTful Web API [Web标准篇]

    REST不是一个标准,而是一种软件应用架构风格.基于SOAP的Web服务采用RPC架构,如果说RPC是一种面向操作的架构风格,而REST则是一种面向资源的架构风格.REST是目前业界更为推崇的构建新一 ...

  2. 我所理解的RESTful Web API [设计篇]

    <我所理解的RESTful Web API [Web标准篇]>Web服务已经成为了异质系统之间的互联与集成的主要手段,在过去一段不短的时间里,Web服务几乎清一水地采用SOAP来构建.构建 ...

  3. 对RESTful Web API的理解与设计思路

    距离上一篇关于Web API的文章(如何实现RESTful Web API的身份验证)有好些时间了,在那篇文章中提到的方法是非常简单而有效的,我在实际的项目中就这么用了,代码经过一段时间的磨合,已经很 ...

  4. About Restful Web Api Something.

    这种轻量级的服务架构目前来说还是比较流行的,比如微信的公众平台的接口开发就是一个很好的案例,提到restful那么他到底是一个什么样的东西? REST(Representational State T ...

  5. 【ASP.NET MVC 学习笔记】- 19 REST和RESTful Web API

    本文参考:http://www.cnblogs.com/willick/p/3441432.html 1.目前使用Web服务的三种主流的方式是:远程过程调用(RPC),面向服务架构(SOA)以及表征性 ...

  6. RESTful Web API 理解

    REST 是一种应用架构风格,不是一种标准,是面向资源架构(ROA)风格,与具体技术平台无关,REST架构的应用未必建立在Web之上,与之对应的是传统的Web Service 采用的面向操作的RPC架 ...

  7. 个人学期总结及Python+Flask+MysqL的web建设技术过程

    一个学期即将过去,我们也迎来了2018年.这个学期,首次接触了web网站开发建设,不仅是这门课程,还有另外一门用idea的gradle框架来制作网页. 很显然,用python语言的flask框架更加简 ...

  8. RESTful Web API 实践

    REST 概念来源 网络应用程序,分为前端和后端两个部分.当前的发展趋势,就是前端设备层出不穷(手机.平板.桌面电脑.其他专用设备...). 因此,必须有一种统一的机制,方便不同的前端设备与后端进行通 ...

  9. Python+Flask+MysqL的web建设技术过程

    一.前言(个人学期总结) 个人总结一下这学期对于Python+Flask+MysqL的web建设技术过程的学习体会,Flask小辣椒框架相对于其他框架而言,更加稳定,不会有莫名其妙的错误,容错性强,运 ...

随机推荐

  1. 等待与希望,.NET Core 的发展壮大

    前几天微软推出了.net core 2.0, 尽管我现在使用的技术栈和微软已经没有一丝瓜葛, 但碰到微软放大招,心里还是瘙痒难当,忍不住偷偷摸摸的体验了一把. 谁叫我是通过微软系技术入的行呢,旧情难忘 ...

  2. 一个基于JRTPLIB的轻量级RTSP客户端(myRTSPClient)——实现篇:(四)用户接口层之处理SDP报文

    当RTSP客户端向RTSP服务端发送DESCRIBE命令时,服务端理应当回复一条SDP报文. 该SDP报文中包含RTSP服务端的基本信息.所能提供的音视频媒体类型以及相应的负载能力,以下是一段SDP示 ...

  3. java集合判断

    java开发中经常需要做集合判断,在这里mark一下,加强记忆 为空判断: null == applyList || applyList.size() ==0 非空判断: applyList != n ...

  4. vc++6.0修改字体

    近期在使用vc++6.0写C程序 问题:vc++自带的字体不太好看 解决办法:修改注册表 1. win+r 运行 regedit 调出注册表编辑器 进入到目录 HKEY_CURRENT_USER\SO ...

  5. Windbg调试关键区(CriticalSection)死锁

    一. 准备工作 这里一个有关键区锁死问题的程序,运行之后依次点击"CS锁死"按钮.右上角退出按钮,程序就会卡死.(图1) 对于眼下的这个问题,界面完全失去响应,这说明负责消息处理的 ...

  6. Sublime Text 2安装图解

    Sublime Text 2安装图解.. ---------------- ---------------- ---------------- ---------------- ----------- ...

  7. HTTP常见状态码

    1.100状态码 1xx:临时响应,表示临时相应并需要请求者继续操作的状态码 100   (继续) 请求者应当继续提出请求. 服务器返回此代码表示已收到请求的第一部分,正在等待其余部分.   101 ...

  8. 读书笔记--C陷阱与缺陷(一)

    要参与C语言项目,于是作者只好重拾C语言(之前都是C++,还是C++方便). 看到大家都推荐看看  C陷阱与缺陷(C traps and pitfalls),于是好奇的开始了这本书的读书之旅. 决定将 ...

  9. spring学习笔记1

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAATQAAAEBCAIAAAB5VM7WAAAgAElEQVR4nOy9Z3gc13n3zZT3efPESZ

  10. javaScript 设计模式系列之三:代理模式

    介绍 代理模式为其他对象提供一种代理以控制对这个对象的访问. 根据代理模式的使用目的不同,代理模式又可以分为多种类型: 远程代理(Remote Proxy) 虚拟代理(Virtual Proxy)如需 ...