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 相关文章推荐
django实现分页的方法
May 26 Python
浅谈python中截取字符函数strip,lstrip,rstrip
Jul 17 Python
Python编程实现输入某年某月某日计算出这一天是该年第几天的方法
Apr 18 Python
Python二叉树的定义及常用遍历算法分析
Nov 24 Python
Python利用turtle库绘制彩虹代码示例
Dec 20 Python
python实现指定文件夹下的指定文件移动到指定位置
Sep 17 Python
Python3基础教程之递归函数简单示例
Jun 07 Python
详解pytorch 0.4.0迁移指南
Jun 16 Python
Python使用百度翻译开发平台实现英文翻译为中文功能示例
Aug 08 Python
详解python内置常用高阶函数(列出了5个常用的)
Feb 21 Python
Python定义一个函数的方法
Jun 15 Python
使用Python解析Chrome浏览器书签的示例
Nov 13 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
全文搜索和替换
2006/10/09 PHP
php strtotime 函数UNIX时间戳
2009/01/14 PHP
php设计模式 Decorator(装饰模式)
2011/06/26 PHP
PHP函数strip_tags的一个bug浅析
2014/05/22 PHP
PHP实现的sqlite数据库连接类
2014/12/12 PHP
php输出含有“#”字符串的方法
2017/01/18 PHP
PHP实现对xml进行简单的增删改查(CRUD)操作示例
2017/05/19 PHP
使用laravel和ECharts实现折线图效果的例子
2019/10/09 PHP
基于php解决json_encode中文UNICODE转码问题
2020/11/10 PHP
javascript数组使用调用方法汇总
2007/12/08 Javascript
表单类各种类型(文本框)失去焦点效果jquery代码
2013/04/26 Javascript
JQuery中如何传递参数如click(),change()等具体实现
2013/04/28 Javascript
鼠标经过tr时,改变tr当前背景颜色
2014/01/13 Javascript
JavaScript函数学习总结以及相关的编程习惯指南
2015/11/16 Javascript
详解在vue-cli中使用路由
2017/09/25 Javascript
vue-router启用history模式下的开发及非根目录部署方法
2018/12/23 Javascript
Layui数据表格判断编辑输入的值,是否为我需要的类型详解
2019/10/26 Javascript
如何在vue 中引入使用jquery
2020/11/10 jQuery
在Python的Flask框架中使用日期和时间的教程
2015/04/21 Python
Python进阶之递归函数的用法及其示例
2018/01/31 Python
在matplotlib的图中设置中文标签的方法
2018/12/13 Python
命令行运行Python脚本时传入参数的三种方式详解
2019/10/11 Python
python脚本调用iftop 统计业务应用流量的思路详解
2019/10/11 Python
pytorch 实现将自己的图片数据处理成可以训练的图片类型
2020/01/08 Python
keras 指定程序在某块卡上训练实例
2020/06/22 Python
突袭HTML5之Javascript API扩展3—本地存储全新体验
2013/01/31 HTML / CSS
俄罗斯和世界各地的酒店预订:Hotels.com俄罗斯
2016/08/19 全球购物
尤为Wconcept中国官网:韩国设计师品牌服饰
2019/01/10 全球购物
internal修饰符起什么作用
2013/12/16 面试题
药学专业大专生的自我评价
2013/12/12 职场文书
学习十八大坚定理想信念心得体会
2014/03/11 职场文书
2014法制宣传日活动总结
2014/07/09 职场文书
机械工程及自动化专业求职信
2014/09/03 职场文书
团队执行力培训心得体会
2015/08/15 职场文书
2019升学宴主持词范本5篇
2019/10/09 职场文书
万能密码的SQL注入漏洞其PHP环境搭建及防御手段
2021/09/04 SQL Server