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常规方法实现数组的全排列
Mar 17 Python
提升Python程序运行效率的6个方法
Mar 31 Python
python 编程之twisted详解及简单实例
Jan 28 Python
Python中selenium实现文件上传所有方法整理总结
Apr 01 Python
flask入门之文件上传与邮件发送示例
Jul 18 Python
python特性语法之遍历、公共方法、引用
Aug 08 Python
浅析python中的迭代与迭代对象
Oct 08 Python
PyCharm+Qt Designer+PyUIC安装配置教程详解
Jun 13 Python
在Python中合并字典模块ChainMap的隐藏坑【推荐】
Jun 27 Python
如何使用python操作vmware
Jul 27 Python
tensorflow对图像进行拼接的例子
Feb 05 Python
Python3.7实现验证码登录方式代码实例
Feb 14 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
基于empty函数的输出详解
2013/06/17 PHP
从PHP $_SERVER相关参数判断是否支持Rewrite模块
2013/09/26 PHP
浅谈ThinkPHP5.0版本和ThinkPHP3.2版本的区别
2017/06/17 PHP
PHP设计模式(三)建造者模式Builder实例详解【创建型】
2020/05/02 PHP
utf-8编码引起js输出中文乱码的解决办法
2010/06/23 Javascript
js返回上一页并刷新代码整理
2012/12/21 Javascript
javascript记录文本框内文字个数检测文字个数变化
2014/10/14 Javascript
jQuery文件上传控件 Uploadify 详解
2016/06/20 Javascript
AngularJS 模块化详解及实例代码
2016/09/14 Javascript
原生JS实现在线问卷调查投票特效
2017/01/03 Javascript
Bootstrap 响应式实用工具实例详解
2017/03/29 Javascript
解决微信二次分享不显示摘要和图片的问题
2017/08/18 Javascript
用Webpack构建Vue项目的实践
2017/11/07 Javascript
JavaScript防止全局变量污染的方法总结
2018/08/02 Javascript
在vue项目中使用md5加密的方法
2018/09/14 Javascript
JS实现关闭小广告特效
2021/01/29 Javascript
js实现抽奖的两种方法
2020/03/19 Javascript
Python ORM框架SQLAlchemy学习笔记之数据查询实例
2014/06/10 Python
Python同时向控制台和文件输出日志logging的方法
2015/05/26 Python
在Python中通过threading模块定义和调用线程的方法
2016/07/12 Python
python中 logging的使用详解
2017/10/25 Python
单利模式及python实现方式详解
2018/03/20 Python
python读取txt文件并取其某一列数据的示例
2019/02/19 Python
Pycharm+Python工程,引用子模块的实现
2020/03/09 Python
python 如何区分return和yield
2020/09/22 Python
html5 canvas简单封装一个echarts实现不了的饼图
2018/06/12 HTML / CSS
Lookfantastic西班牙官网:英国知名美妆购物网站
2018/06/13 全球购物
人民教师的自我评价分享
2014/02/21 职场文书
大学生社会实践自我鉴定
2014/03/24 职场文书
法学求职信
2014/06/22 职场文书
领导党的群众路线教育实践活动个人对照检查材料
2014/09/23 职场文书
群众路线专项整治工作情况报告
2014/10/28 职场文书
办公室个人总结
2015/02/28 职场文书
Windows 11上手初体验:任务栏和开始菜单等迎来大改
2021/11/21 数码科技
Spring this调用当前类方法无法拦截的示例代码
2022/03/20 Java/Android
python中pycryto实现数据加密
2022/04/29 Python