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脚本实现查找webshell的方法
Jul 31 Python
python实现从一组颜色中找出与给定颜色最接近颜色的方法
Mar 19 Python
详解Django框架中用户的登录和退出的实现
Jul 23 Python
探究python中open函数的使用
Mar 01 Python
便捷提取python导入包的属性方法
Oct 15 Python
在Python中将函数作为另一个函数的参数传入并调用的方法
Jan 22 Python
浅谈python之高阶函数和匿名函数
Mar 21 Python
Python类中方法getitem和getattr详解
Aug 30 Python
使用python实现哈希表、字典、集合操作
Dec 22 Python
python 基于opencv操作摄像头
Dec 24 Python
解决Pytorch中关于model.eval的问题
May 22 Python
python使用BeautifulSoup 解析HTML
Apr 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
不用iconv库的gb2312与utf-8的互换函数
2006/10/09 PHP
NO3第三帝国留言簿制作过程
2006/10/09 PHP
imgAreaSelect 中文文档帮助说明
2011/10/08 Javascript
关于图片按比例自适应缩放的js代码
2011/10/30 Javascript
这些年、我收集的JQuery代码小结
2012/08/01 Javascript
js获取IFRAME当前的URL的方法
2013/11/13 Javascript
Node.js的包详细介绍
2015/01/14 Javascript
js下将金额数字每三位一逗号分隔
2016/02/19 Javascript
javascript表单控件实例讲解
2016/09/13 Javascript
js根据json数据中的某一个属性来给数据分组的方法
2018/10/08 Javascript
vue组件从开发到发布的实现步骤
2018/11/11 Javascript
基于Proxy的小程序状态管理实现
2019/06/14 Javascript
taro小程序添加骨架屏的实现代码
2019/11/15 Javascript
如何优雅地在Node应用中进行错误异常处理
2019/11/25 Javascript
微信小程序个人中心的列表控件实现代码
2020/04/26 Javascript
Python 用户登录验证的小例子
2013/03/06 Python
python条件和循环的使用方法
2013/11/01 Python
python文件和目录操作方法大全(含实例)
2014/03/12 Python
Python数组条件过滤filter函数使用示例
2014/07/22 Python
python使用pil生成图片验证码的方法
2015/05/08 Python
Python键盘输入转换为列表的实例
2018/06/23 Python
Python小白必备的8个最常用的内置函数(推荐)
2019/04/03 Python
Python数据类型之Tuple元组实例详解
2019/05/08 Python
详解python深浅拷贝区别
2019/06/24 Python
pytorch 可视化feature map的示例代码
2019/08/20 Python
Windows10下 python3.7 安装 facenet的教程
2019/09/10 Python
django使用F方法更新一个对象多个对象字段的实现
2020/03/28 Python
Django media static外部访问Django中的图片设置教程
2020/04/07 Python
Python模拟登入的N种方式(建议收藏)
2020/05/31 Python
HTML5 Web Database 数据库的SQL语句的使用方法
2012/12/09 HTML / CSS
幼儿园教育教学反思
2014/01/31 职场文书
幼儿园感恩节活动方案2014
2014/10/11 职场文书
2015年世界粮食日演讲稿
2015/03/20 职场文书
公司财务管理制度
2015/08/04 职场文书
工作报告范文
2019/06/20 职场文书
Python实现机器学习算法的分类
2021/06/03 Python