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中使用模块的教程
Apr 27 Python
使用Python的urllib和urllib2模块制作爬虫的实例教程
Jan 20 Python
200行自定义python异步非阻塞Web框架
Mar 15 Python
python selenium UI自动化解决验证码的4种方法
Jan 05 Python
python实现一个简单的并查集的示例代码
Mar 19 Python
pygame实现雷电游戏雏形开发
Nov 20 Python
python 随机生成10位数密码的实现代码
Jun 27 Python
python代码区分大小写吗
Jun 17 Python
利用python如何实现猫捉老鼠小游戏
Dec 04 Python
pycharm 多行批量缩进和反向缩进快捷键介绍
Jan 15 Python
Python捕获、播放和保存摄像头视频并提高视频清晰度和对比度
Apr 14 Python
Python测试框架pytest高阶用法全面详解
Jun 01 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
也谈php网站在线人数统计
2008/04/09 PHP
PHP 透明水印生成代码
2012/08/27 PHP
php自动获取关键字的方法
2015/01/06 PHP
如何批量清理系统临时文件(语言:C#、 C/C++、 php 、python 、java )
2016/02/01 PHP
laravel框架关于搜索功能的实现
2018/03/15 PHP
使用PHP反射机制来构造&quot;CREATE TABLE&quot;的sql语句
2019/03/21 PHP
laravel实现Auth认证,登录、注册后的页面回跳方法
2019/09/30 PHP
tp5.1 框架数据库高级查询技巧实例总结
2020/05/25 PHP
关于jQuery object and DOM element
2013/04/15 Javascript
js 获取元素下面所有li的两种方法
2014/04/14 Javascript
JS比较2个日期间隔的示例代码
2014/04/15 Javascript
在JavaScript中操作时间之setYear()方法的使用
2015/06/12 Javascript
浅析AngularJs HTTP响应拦截器
2015/12/28 Javascript
JS实现动态增加和删除li标签行的实例代码
2016/10/16 Javascript
JavaScript实现为事件句柄绑定监听函数的方法分析
2017/11/14 Javascript
详解vue-cli之webpack3构建全面提速优化
2017/12/25 Javascript
Node Puppeteer图像识别实现百度指数爬虫的示例
2018/02/22 Javascript
详解使用jest对vue项目进行单元测试
2018/09/07 Javascript
[01:57]2016完美“圣”典风云人物:国士无双专访
2016/12/04 DOTA
基于python(urlparse)模板的使用方法总结
2017/10/13 Python
Python制作exe文件简单流程
2019/01/24 Python
python使用Plotly绘图工具绘制水平条形图
2020/03/25 Python
基于sklearn实现Bagging算法(python)
2019/07/11 Python
Python3 assert断言实现原理解析
2020/03/02 Python
python实点云分割k-means(sklearn)详解
2020/05/28 Python
PyQt5.6+pycharm配置以及pyinstaller生成exe(小白教程)
2020/06/02 Python
python3爬虫中异步协程的用法
2020/07/10 Python
Python基于argparse与ConfigParser库进行入参解析与ini parser
2021/02/02 Python
Canal官网:巴西女性时尚品牌
2019/10/16 全球购物
英国最受欢迎的母婴精品品牌:JoJo Maman BéBé
2021/02/17 全球购物
办公室秘书自我鉴定
2014/01/18 职场文书
批评与自我批评总结
2014/10/17 职场文书
婚礼伴郎致辞
2015/07/28 职场文书
2016中秋节广告语
2016/01/28 职场文书
六种css3实现的边框过渡效果
2021/04/22 HTML / CSS
Win11快速关闭所有广告推荐
2022/04/19 数码科技