使用Python & Flask 实现RESTful Web API的实例


Posted in Python onSeptember 19, 2017

环境安装:

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 = {'1':'john', '2':'steve', '3':'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的实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python运行其他程序的实现方法
Jul 14 Python
Python 模拟员工信息数据库操作的实例
Oct 23 Python
Python使用functools实现注解同步方法
Feb 06 Python
Python中常见的异常总结
Feb 20 Python
windows下python和pip安装教程
May 25 Python
Python数据集切分实例
Dec 08 Python
Python 的AES加密与解密实现
Jul 09 Python
Win10+GPU版Pytorch1.1安装的安装步骤
Sep 27 Python
导入tensorflow时报错:cannot import name 'abs'的解决
Oct 10 Python
python add_argument()用法解析
Jan 29 Python
Python基于stuck实现scoket文件传输
Apr 02 Python
如何使用PyCharm引入需要使用的包的方法
Sep 22 Python
python基本语法练习实例
Sep 19 #Python
基于python3 类的属性、方法、封装、继承实例讲解
Sep 19 #Python
浅谈python中列表、字符串、字典的常用操作
Sep 19 #Python
Python 文件操作的详解及实例
Sep 18 #Python
python Socket之客户端和服务端握手详解
Sep 18 #Python
Python基于time模块求程序运行时间的方法
Sep 18 #Python
Python使用当前时间、随机数产生一个唯一数字的方法
Sep 18 #Python
You might like
PHP 5.0 Pear安装方法
2006/12/06 PHP
使用PHP实现密保卡功能实现代码&amp;lt;打包下载直接运行&amp;gt;
2011/10/09 PHP
浅析PHP中strlen和mb_strlen的区别
2014/08/31 PHP
浅谈PHP错误类型及屏蔽方法
2017/05/27 PHP
Yii2语言国际化自动配置详解
2018/08/22 PHP
通过js脚本复制网页上的一个表格的不错实现方法
2006/12/29 Javascript
XHTML下,JS浮动代码失效的问题
2009/11/12 Javascript
JQuery里面的几种选择器 查找满足条件的元素$(&quot;#控件ID&quot;)
2011/08/23 Javascript
JS中的public和private对象,即static修饰符
2012/01/18 Javascript
Extjs根据条件设置表格某行背景色示例
2014/07/23 Javascript
NodeJS使用formidable实现文件上传
2016/10/27 NodeJs
详解如何较好的使用js
2016/12/16 Javascript
JS实现的简单拖拽功能示例
2017/03/13 Javascript
JavaScript数据结构之二叉查找树的定义与表示方法
2017/04/12 Javascript
HTML5+JS+JQuery+ECharts实现异步加载问题
2017/12/16 jQuery
vue父组件向子组件(props)传递数据的方法
2018/01/02 Javascript
Vue搭建后台系统需要注意的问题
2019/11/08 Javascript
微信小程序实现watch监听
2020/06/04 Javascript
如何构建一个Vue插件并生成npm包
2020/10/26 Javascript
python 字典中取值的两种方法小结
2018/08/02 Python
利用nohup来开启python文件的方法
2019/01/14 Python
python socket通信编程实现文件上传代码实例
2019/12/14 Python
使用PyCharm安装pytest及requests的问题
2020/07/31 Python
PyCharm vs VSCode,作为python开发者,你更倾向哪种IDE呢?
2020/08/17 Python
让IE可以变相支持CSS3选择器
2010/01/21 HTML / CSS
CSS3模块的目前的状况分析
2010/02/24 HTML / CSS
CSS3 选择器 属性选择器介绍
2012/01/21 HTML / CSS
Html5跳转到APP指定页面的实现
2020/01/14 HTML / CSS
高街生活方式全球在线商店:AZBRO
2017/08/26 全球购物
西班牙品牌鞋子、服装和配饰在线商店:Esdemarca
2021/02/17 全球购物
高校自主招生自荐信
2013/12/09 职场文书
军训自我鉴定怎么写
2014/02/13 职场文书
2014法制宣传日活动总结范文
2014/11/01 职场文书
2014年超市工作总结
2014/11/19 职场文书
MySQL学习必备条件查询数据
2022/03/25 MySQL
Java 超详细讲解设计模式之中的抽象工厂模式
2022/03/25 Java/Android