使用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实现通过shelve修改对象实例
Sep 26 Python
Ubuntu 下 vim 搭建python 环境 配置
Jun 12 Python
浅谈使用Python变量时要避免的3个错误
Oct 30 Python
python中is与双等于号“==”的区别示例详解
Nov 21 Python
python用post访问restful服务接口的方法
Dec 07 Python
Python提取特定时间段内数据的方法实例
Apr 01 Python
TFRecord格式存储数据与队列读取实例
Jan 21 Python
pytorch中使用cuda扩展的实现示例
Feb 12 Python
python pyqtgraph 保存图片到本地的实例
Mar 14 Python
详解python logging日志传输
Jul 01 Python
Python headers请求头如何实现快速添加
Nov 03 Python
Numpy数组的广播机制的实现
Nov 03 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 透明水印生成代码
2012/08/27 PHP
codeigniter使用技巧批量插入数据实例方法分享
2013/12/31 PHP
PHP模板引擎Smarty之配置文件在模板变量中的使用方法示例
2016/04/11 PHP
php 生成加密公钥加密私钥实例详解
2017/06/16 PHP
PHP 进度条函数的简单实例
2017/09/19 PHP
PHP Post获取不到非表单数据的问题解决办法
2018/02/27 PHP
PHP进阶学习之垃圾回收机制详解
2019/06/18 PHP
Jquery replace 字符替换实现代码
2010/12/02 Javascript
JS操作数据库的实例代码
2013/10/17 Javascript
jquery常用函数与方法汇总
2015/09/01 Javascript
javascript中replace使用方法总结
2017/03/01 Javascript
vue-hook-form使用详解
2017/04/07 Javascript
Vue使用vue-cli创建项目
2017/09/01 Javascript
JavaScript实现鼠标滚轮控制页面图片切换功能示例
2017/10/14 Javascript
canvas绘制爱心的几种方法总结(推荐)
2017/10/31 Javascript
JavaScript实现微信号随机切换代码
2018/03/09 Javascript
在vue中使用Autoprefixed的方法
2018/07/27 Javascript
vue自定义tap指令及tap事件的实现
2018/09/18 Javascript
记录一次完整的react hooks实践
2019/03/11 Javascript
解决一个微信号同时支持多个环境网页授权问题
2019/08/07 Javascript
小程序实现层叠卡片滑动效果
2019/08/26 Javascript
[02:39]我与DAC之Newbee.Moogy:从论坛到TI
2018/03/26 DOTA
[35:55]完美世界DOTA2联赛PWL S3 Rebirth vs CPG 第一场 12.11
2020/12/13 DOTA
python爬虫爬取淘宝商品信息
2018/02/23 Python
python DataFrame 取差集实例
2019/01/30 Python
详解Python3注释知识点
2019/02/19 Python
解决Pytorch 加载训练好的模型 遇到的error问题
2020/01/10 Python
Python基于wordcloud及jieba实现中国地图词云图
2020/06/09 Python
python中执行smtplib失败的处理方法
2020/07/01 Python
css3 按钮样式简单可扩展创建
2013/03/18 HTML / CSS
会计系个人求职信范文分享
2013/12/20 职场文书
拾金不昧锦旗标语
2014/06/27 职场文书
团队拓展训练心得体会
2016/01/12 职场文书
2016大学生就业指导课心得体会
2016/01/15 职场文书
用 Python 元类的特性实现 ORM 框架
2021/05/19 Python
springboot读取nacos配置文件
2022/05/20 Java/Android