使用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解决鸡兔同笼问题的方法
Dec 20 Python
Python使用matplotlib简单绘图示例
Feb 01 Python
python爬取个性签名的方法
Jun 17 Python
使用python实现http及ftp服务进行数据传输的方法
Oct 26 Python
PyQt5实现五子棋游戏(人机对弈)
Mar 24 Python
python3利用ctypes传入一个字符串类型的列表方法
Feb 12 Python
Python使用LDAP做用户认证的方法
Jun 20 Python
Python无头爬虫下载文件的实现
Apr 02 Python
Python 中由 yield 实现异步操作
May 04 Python
Python自定义sorted排序实现方法详解
Sep 18 Python
Python基础之hashlib模块详解
May 06 Python
Python函数式编程中itertools模块详解
Sep 15 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
mysql数据库差异比较的PHP代码
2012/02/05 PHP
PHP微信红包生成代码分享
2016/10/06 PHP
jquery-easyui关闭tab自动切换到前一个tab
2010/07/29 Javascript
JS继承 笔记
2011/07/13 Javascript
iframe异步加载实现点击左边菜单加载右边内容实例讲解
2013/03/04 Javascript
window.location.href的用法(动态输出跳转)
2014/08/09 Javascript
jQuery动态背景图片效果实现方法
2015/07/03 Javascript
jQuery制作圣诞主题页面 更像是爱情影集
2016/08/10 Javascript
jQuery实现可展开折叠的导航效果示例
2016/09/12 Javascript
Bootstrap源码解读标签、徽章、缩略图和警示框(8)
2016/12/26 Javascript
javascript设计模式之中介者模式学习笔记
2017/02/15 Javascript
JavaScript自定义文本框光标
2017/03/05 Javascript
ES6解构赋值实例详解
2017/10/31 Javascript
vue脚手架中配置Sass的方法
2018/01/04 Javascript
JQuery获取元素尺寸、位置及页面滚动事件应用示例
2019/05/14 jQuery
[00:12]DAC2018 no[o]ne亮相SOLO赛 他是否如他的id一样无人可挡?
2018/04/06 DOTA
Python标准库defaultdict模块使用示例
2015/04/28 Python
Python常见异常分类与处理方法
2017/06/04 Python
Django 视图层(view)的使用
2018/11/09 Python
Python学习笔记之列表和成员运算符及列表相关方法详解
2019/08/22 Python
pytorch实现Tensor变量之间的转换
2020/02/17 Python
ubuntu 安装pyqt5和卸载pyQt5的方法
2020/03/24 Python
用HTML5.0制作网页的教程
2010/05/30 HTML / CSS
Emporio Armani腕表天猫官方旗舰店:乔治·阿玛尼为年轻人设计的副线品牌
2017/07/02 全球购物
比驿:全球酒店比价网
2018/06/20 全球购物
美国鲍勃商店:Bob’s Stores
2018/07/22 全球购物
西班牙最大的在线滑板和街头服饰商店:Fillow.net
2019/04/15 全球购物
美团网旗下网上订餐平台:美团外卖
2020/03/05 全球购物
移动通信行业实习自我鉴定
2013/09/28 职场文书
自我评价范文分享
2014/01/04 职场文书
土建施工员岗位职责
2014/07/16 职场文书
开展创先争优活动总结
2014/08/28 职场文书
办公室个人总结
2015/02/28 职场文书
小学重阳节活动总结
2015/03/24 职场文书
SpringAop日志找不到方法的处理
2021/06/21 Java/Android
MySQL系列之五 视图、存储函数、存储过程、触发器
2021/07/02 MySQL