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中用于检查英文字母大写的isupper()方法
May 19 Python
python黑魔法之编码转换
Jan 25 Python
python使用TensorFlow进行图像处理的方法
Feb 28 Python
从django的中间件直接返回请求的方法
May 30 Python
Python使用add_subplot与subplot画子图操作示例
Jun 01 Python
Python小工具之消耗系统指定大小内存的方法
Dec 03 Python
Django Sitemap 站点地图的实现方法
Apr 29 Python
python和mysql交互操作实例详解【基于pymysql库】
Jun 04 Python
树莓派使用python-librtmp实现rtmp推流h264的方法
Jul 22 Python
Python reversed反转序列并生成可迭代对象
Oct 22 Python
Python中requests做接口测试的方法
May 30 Python
Python3接口性能测试实例代码
Jun 20 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实现手机号码中间四位用星号(*)隐藏的自定义函数分享
2014/09/27 PHP
php对二维数组进行相关操作(排序、转换、去空白等)
2015/11/04 PHP
微信公众平台DEMO(PHP)
2016/05/04 PHP
PHP实践教程之过滤、验证、转义与密码详解
2017/07/24 PHP
改变javascript函数内部this指针指向的三种方法
2010/04/23 Javascript
js读取本地excel文档数据的代码
2010/11/11 Javascript
DIY jquery plugin - tabs标签切换实现代码
2010/12/11 Javascript
jquery 滚动条事件简单实例
2013/07/12 Javascript
将两个div左右并列显示并实现点击标题切换内容
2013/10/22 Javascript
纯javascript实现分页(两种方法)
2015/08/26 Javascript
Bootstrap导航栏各元素操作方法(表单、按钮、文本)
2015/12/28 Javascript
jQuery ajax 当async为false时解决同步操作失败的问题
2016/11/18 Javascript
浅谈Nodejs中的作用域问题
2016/12/26 NodeJs
原生JS中slice()方法和splice()区别
2017/03/06 Javascript
JS实现导出Excel的五种方法详解【附源码下载】
2018/03/15 Javascript
webpack4手动搭建Vue开发环境实现todoList项目的方法
2019/05/16 Javascript
从零撸一个pc端vue的ui组件库( 计数器组件 )
2019/08/08 Javascript
详解javascript中var与ES6规范中let、const区别与用法
2020/01/11 Javascript
[09:43]DOTA2每周TOP10 精彩击杀集锦vol.5
2014/06/25 DOTA
[01:36]DOTA2完美大师赛趣味视频之与队友相处的十万个技巧
2017/11/19 DOTA
[00:17]天涯墨客一技能展示
2018/08/25 DOTA
Python3基础之输入和输出实例分析
2014/08/18 Python
Python使用matplotlib实现基础绘图功能示例
2018/07/03 Python
Python字符串逆序的实现方法【一题多解】
2019/02/18 Python
python画图把时间作为横坐标的方法
2019/07/07 Python
Django为窗体加上防机器人的验证码功能过程解析
2019/08/14 Python
关于python字符串方法分类详解
2019/08/20 Python
python中Pexpect的工作流程实例讲解
2021/03/02 Python
CSS3实现文字描边的2种方法(小结)
2020/02/14 HTML / CSS
Html5移动端适配IphoneX等机型的方法
2019/06/25 HTML / CSS
美国滑雪和滑雪板商店:Buckman
2018/03/03 全球购物
《小草和大树》教学反思
2014/02/16 职场文书
人力资源管理专业自荐书
2014/07/07 职场文书
2015年七一建党节活动总结
2015/03/20 职场文书
前台接待岗位职责范本
2015/04/03 职场文书
工作态度检讨书范文
2015/05/06 职场文书