python Flask实现restful api service


Posted in Python onDecember 04, 2017

一直在用node.js做后端,要逐步涉猎大数据范围,注定绕不过python,因此决定把一些成熟的东西用python来重写,一是开拓思路、通过比较来深入学习python;二是有目标,有动力,希望能持之以恒的坚持下去。

项目介绍

用python语言来写一个restful api service,数据库使用mysql。因为只做后端微服务,并且ORM的实现方式,采用自动生成SQL的方式来完成,因此选择了轻量级的flask作为web框架。如此选择,主要目的是针对中小规模的网络应用,能充分利用关系数据库的种种优势,来实现丰富的现代互联网应用。

REST的六个特性:

  1. Client-Server:服务器端与客户端分离。
  2. Stateless(无状态):每次客户端请求必需包含完整的信息,换句话说,每一次请求都是独立的。
  3. Cacheable(可缓存):服务器端必需指定哪些请求是可以缓存的。
  4. Layered System(分层结构):服务器端与客户端通讯必需标准化,服务器的变更并不会影响客户端。
  5. Uniform Interface(统一接口):客户端与服务器端的通讯方法必需是统一的。
  6. Code on demand(按需执行代码?):服务器端可以在上下文中执行代码或者脚本

restful api

restful api 的概念就不介绍了。这里说一下我们实现协议形式:

[GET]/rs/user/{id}/key1/value1/key2/value2/.../keyn/valuen     
[POST]/rs/user[/{id}]     
[PUT]/rs/user/{id}
[DELETE]/rs/user/{id}/key1/value1/key2/value2/.../keyn/valuen

说明:

  1. rs为资源标识;
  2. 第二节,user,会被解析为数据库表名;
  3. 查询时,id为空或0时,id会被忽略,即为列表查询;
  4. 新建和修改,除接收form表单外,url中的id参数也会被合并到参数集合中;
  5. 删除同查询。

让flask支持正则表达式

flask默认路由不支持正则表达式,而我需要截取完整的URL自己来解析,经查询,按以下步骤很容易完成任务。

  1. 使用werkzeug库 :from werkzeug.routing import BaseConverter
  2. 定义转换器:
class RegexConverter(BaseConverter):

  def __init__(self, map, *args):
    self.map = map
    self.regex = args[0]
  1. 注册转换器 : app.url_map.converters['regex'] = RegexConverter
  2. 用正则来截取url : @app.route('/rs/<regex(".*"):query_url>', methods=['PUT', 'DELETE', 'POST', 'GET'])

几点疑问:

  1. 正则(.*)理论上应该是匹配任何除回车的所有字符,但不知道为什么,在这里不识别问号(?)
  2. 我用request.data来取表单数据,为何request.form取不到?
  3. '/rs/<regex("."):query_url>'后若加个反斜杠('/rs/<regex("."):query_url>/'),request.data就取不到数据,为什么?

解析json数据

解析json数据很容易,但我需要对客户端送上来的数据进行校验,下面是用异常处理又只解析一次的解决方案。

def check_json_format(raw_msg):
  try:
    js = json.loads(raw_msg, encoding='utf-8')
  except ValueError:
    return False, {}
  return True, js

URL解析

按既定协议解析URL,提取表名,为生成sql组合参数集合。

@app.route('/rs/<regex(".*"):query_url>', methods=['PUT', 'DELETE', 'POST', 'GET'])
def rs(query_url):
  (flag, params) = check_json_format(request.data)

  urls = query_url.split('/')
  url_len = len(urls)
  if url_len < 1 or url_len > 2 and url_len % 2 == 1:
    return "The params is wrong."

  ps = {}
  for i, al in enumerate(urls):
    if i == 0:
      table = al
    elif i == 1:
      idd = al
    elif i > 1 and i % 2 == 0:
      tmp = al
    else:
      ps[tmp] = al

  ps['table'] = table
  if url_len > 1:
    ps['id'] = idd
  if request.method == 'POST' or request.method == 'PUT':
    params = dict(params, **{'table': ps.get('table'), 'id': ps.get('id')})
  if request.method == 'GET' or request.method == 'DELETE':
    params = ps
  return jsonify(params)

完整代码

git clone https://github.com/zhoutk/pyrest.git
cd rest
export FLASK_APP=index.py
flask run

小结

今天利用flask完成了web基础架构,能够正确解析URL,提取客户端提交的数据,按请求的不同方式来组合我们需要的数据。希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python类装饰器用法实例
Jun 04 Python
Linux系统上Nginx+Python的web.py与Django框架环境
Dec 25 Python
Python3.4实现远程控制电脑开关机
Feb 22 Python
Python3之简单搭建自带服务器的实例讲解
Jun 04 Python
django 快速启动数据库客户端程序的方法示例
Aug 16 Python
Python 操作mysql数据库查询之fetchone(), fetchmany(), fetchall()用法示例
Oct 17 Python
python实现逢七拍腿小游戏的思路详解
May 26 Python
python 基于opencv去除图片阴影
Jan 26 Python
Python实现Telnet自动连接检测密码的示例
Apr 16 Python
浅谈Python基础之列表那些事儿
May 11 Python
pytorch 实现变分自动编码器的操作
May 24 Python
linux中nohup和后台运行进程查看及终止
Jun 24 Python
浅谈Python中带_的变量或函数命名
Dec 04 #Python
Python中对象的引用与复制代码示例
Dec 04 #Python
Python3 Random模块代码详解
Dec 04 #Python
利用python爬取斗鱼app中照片方法实例
Dec 03 #Python
CentOS 6.5中安装Python 3.6.2的方法步骤
Dec 03 #Python
python3利用smtplib通过qq邮箱发送邮件方法示例
Dec 03 #Python
Python中类的初始化特殊方法
Dec 01 #Python
You might like
法压式咖啡之制作法
2021/03/03 冲泡冲煮
php算开始时间到过期时间的相隔的天数
2011/01/12 PHP
joomla jce editor 解决上传中文名文件失败问题
2013/06/09 PHP
tp5框架无刷新分页实现方法分析
2019/09/26 PHP
JS的replace方法介绍
2012/10/20 Javascript
简易js代码实现计算器操作
2013/04/15 Javascript
Egret引擎开发指南之运行项目
2014/09/03 Javascript
jQuery实现图片轮播特效代码分享
2015/09/15 Javascript
JavaScript实现图片自动加载的瀑布流效果
2016/04/11 Javascript
Bootstrap3.0学习教程之JS折叠插件
2016/05/27 Javascript
jQuery访问浏览器本地存储cookie、localStorage和sessionStorage的基本用法
2017/10/20 jQuery
Vue+webpack+Element 兼容问题总结(小结)
2018/08/16 Javascript
vue2.0 使用element-ui里的upload组件实现图片预览效果方法
2018/09/04 Javascript
微信小程序实现一张或多张图片上传(云开发)
2019/09/25 Javascript
[51:29]完美世界DOTA2联赛循环赛 Matador vs Forest BO2第一场 11.05
2020/11/05 DOTA
详解Python的Django框架中的通用视图
2015/05/04 Python
python实现音乐下载的统计
2018/06/20 Python
python使用Matplotlib画饼图
2018/09/25 Python
python对列进行平移变换的方法(shift)
2019/01/10 Python
Django 导出项目依赖库到 requirements.txt过程解析
2019/08/23 Python
Django实现whoosh搜索引擎使用jieba分词
2020/04/08 Python
简单了解pytest测试框架setup和tearDown
2020/04/14 Python
pandas DataFrame 数据选取,修改,切片的实现
2020/04/24 Python
Python ellipsis 的用法详解
2020/11/20 Python
html5 横向滑动导航栏的方法示例
2020/05/08 HTML / CSS
阿迪达斯俄罗斯官方商城:adidas俄罗斯
2017/03/08 全球购物
全球知名的珠宝首饰品牌:Kay Jewelers
2018/02/11 全球购物
Muziker英国:中欧最大的音乐家商店
2020/02/05 全球购物
写一个函数返回1+2+3+…+n的值(假定结果不会超过长整型变量的范围)
2014/09/05 面试题
如何整合JQuery和Prototype
2014/01/31 面试题
毕业生的自我评价
2013/12/30 职场文书
会计大学生职业生涯规划书范文
2014/01/13 职场文书
普通党员个人整改措施
2014/10/27 职场文书
2014年内勤工作总结
2014/11/24 职场文书
文明倡议书
2015/01/19 职场文书
2015年网络管理员工作总结
2015/05/21 职场文书