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实现登陆知乎获得个人收藏并保存为word文件
Mar 16 Python
使用py2exe在Windows下将Python程序转为exe文件
Mar 04 Python
python基础教程之匿名函数lambda
Jan 17 Python
关于Python中异常(Exception)的汇总
Jan 18 Python
python数据结构之链表详解
Sep 12 Python
python实现分页效果
Oct 25 Python
Django学习教程之静态文件的调用详解
May 08 Python
利用Python将文本中的中英文分离方法
Oct 31 Python
浅谈python实现Google翻译PDF,解决换行的问题
Nov 28 Python
浅谈Python3中strip()、lstrip()、rstrip()用法详解
Apr 29 Python
python障碍式期权定价公式
Jul 19 Python
Pytorch Tensor基本数学运算详解
Dec 30 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中路径问题的解决方案
2006/10/09 PHP
在php MYSQL中插入当前时间
2008/04/06 PHP
PHP获取当前文件所在目录 getcwd()函数
2009/05/13 PHP
php 接口类与抽象类的实际作用
2009/11/26 PHP
php实现文件管理与基础功能操作
2017/03/21 PHP
JavaScript 和 Java 的区别浅析
2013/07/31 Javascript
使用text方法获取Html元素文本信息示例
2014/09/01 Javascript
jQuery中bind(),live(),delegate(),on()绑定事件方法实例详解
2016/01/19 Javascript
webpack配置proxyTable时pathRewrite无效的解决方法
2018/12/13 Javascript
jQuery 图片查看器插件 Viewer.js用法简单示例
2020/04/04 jQuery
浅谈vue的第一个commit分析
2020/06/08 Javascript
python实现文件快照加密保护的方法
2015/06/30 Python
详解字典树Trie结构及其Python代码实现
2016/06/03 Python
关于Python如何避免循环导入问题详解
2017/09/14 Python
Django 路由系统URLconf的使用
2018/10/11 Python
python3实现网络爬虫之BeautifulSoup使用详解
2018/12/19 Python
python之Flask实现简单登录功能的示例代码
2018/12/24 Python
Python Cookie 读取和保存方法
2018/12/28 Python
python同步windows和linux文件
2019/08/29 Python
tensorflow实现tensor中满足某一条件的数值取出组成新的tensor
2020/01/04 Python
Python列表解析操作实例总结
2020/02/26 Python
python + selenium 刷B站播放量的实例代码
2020/06/12 Python
python 爬取英雄联盟皮肤并下载的示例
2020/12/04 Python
css3的transition效果和transfor效果示例介绍
2013/10/30 HTML / CSS
html5手机端页面可以向右滑动导致样式受影响的问题
2018/06/20 HTML / CSS
详解Canvas 跨域脱坑实践
2018/11/07 HTML / CSS
日本最佳原创设计品牌:Felissimo(芬理希梦)
2019/03/19 全球购物
俄罗斯最大的香水和化妆品网上商店:Randewoo
2020/11/05 全球购物
日本最大的彩色隐形眼镜销售网站:CharmColor
2020/09/09 全球购物
包装类的功能、种类、常用方法
2012/01/27 面试题
EJB与JAVA BEAN的区别
2016/08/29 面试题
公司聘任书模板
2014/03/29 职场文书
文明社区申报材料
2014/08/21 职场文书
2014年初三班主任工作总结
2014/12/05 职场文书
python爬虫框架feapde的使用简介
2021/04/20 Python
Java用自带的Image IO给图片添加水印
2021/06/15 Java/Android