使用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处理python编码问题
Mar 13 Python
利用Celery实现Django博客PV统计功能详解
May 08 Python
Python3 模块、包调用&amp;路径详解
Oct 25 Python
Python3 SSH远程连接服务器的方法示例
Dec 29 Python
对python字典过滤条件的实例详解
Jan 22 Python
Django rstful登陆认证并检查session是否过期代码实例
Aug 13 Python
python通过matplotlib生成复合饼图
Feb 06 Python
基于Python爬取爱奇艺资源过程解析
Mar 02 Python
python zip()函数的使用示例
Sep 23 Python
python报错TypeError: ‘NoneType‘ object is not subscriptable的解决方法
Nov 05 Python
scrapy-splash简单使用详解
Feb 21 Python
Python爬虫之爬取哔哩哔哩热门视频排行榜
Apr 28 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 is_file 判断给定文件名是否为一个正常的文件
2010/05/10 PHP
php 中文字符串首字母的获取函数分享
2013/11/04 PHP
Stop SQL Server
2007/06/21 Javascript
Jquery中getJSON在asp.net中的使用说明
2011/03/10 Javascript
读jQuery之十二 删除事件核心方法
2011/07/31 Javascript
getElementByIdx_x js自定义getElementById函数
2012/01/24 Javascript
javascript实现的DES加密示例
2013/10/30 Javascript
14款NodeJS Web框架推荐
2014/07/11 NodeJs
jquery实现仿Flash的横向滑动菜单效果代码
2015/09/17 Javascript
jQuery实现简单隔行变色的方法
2016/02/20 Javascript
JS组件Bootstrap实现弹出框效果代码
2016/04/26 Javascript
jQuery插件dataTables添加序号列的方法
2016/07/06 Javascript
关于JSON与JSONP简单总结
2016/08/16 Javascript
值得分享和收藏的xmlplus组件学习教程
2017/05/05 Javascript
详解a++和++a的区别
2017/08/30 Javascript
分析JavaScript数组操作难点
2017/12/18 Javascript
vue-router重定向和路由别名的使用讲解
2019/01/19 Javascript
vue路由分文件拆分管理详解
2020/08/13 Javascript
[01:03]PWL开团时刻DAY6——别打我
2020/11/05 DOTA
Python操作列表的常用方法分享
2014/02/13 Python
python实现网页链接提取的方法分享
2014/02/25 Python
Python采用Django制作简易的知乎日报API
2016/08/03 Python
python 实现在Excel末尾增加新行
2018/05/02 Python
Pandas实现数据类型转换的一些小技巧汇总
2018/05/07 Python
python实现逆序输出一个数字的示例讲解
2018/06/25 Python
对python中array.sum(axis=?)的用法介绍
2018/06/28 Python
python绘制已知点的坐标的直线实例
2019/07/04 Python
利用Python模拟登录pastebin.com的实现方法
2019/07/12 Python
python3.x 生成3维随机数组实例
2019/11/28 Python
房屋转让协议书范本
2014/04/11 职场文书
关于感恩的演讲稿400字
2014/08/26 职场文书
施工员岗位职责
2015/02/10 职场文书
宾馆前台接待岗位职责
2015/04/02 职场文书
开工典礼致辞
2015/07/29 职场文书
Nginx下配置Https证书详细过程
2021/04/01 Servers
mysql 获取时间方式
2022/03/20 MySQL