用Python编写web API的教程


Posted in Python onApril 30, 2015

自从Roy Fielding博士在2000年他的博士论文中提出REST(Representational State Transfer)风格的软件架构模式后,REST就基本上迅速取代了复杂而笨重的SOAP,成为Web API的标准了。

什么是Web API呢?

如果我们想要获取一篇Blog,输入http://localhost:9000/blog/123,就可以看到id为123的Blog页面,但这个结果是HTML页面,它同时混合包含了Blog的数据和Blog的展示两个部分。对于用户来说,阅读起来没有问题,但是,如果机器读取,就很难从HTML中解析出Blog的数据。

如果一个URL返回的不是HTML,而是机器能直接解析的数据,这个URL就可以看成是一个Web API。比如,读取http://localhost:9000/api/blogs/123,如果能直接返回Blog的数据,那么机器就可以直接读取。

REST就是一种设计API的模式。最常用的数据格式是JSON。由于JSON能直接被JavaScript读取,所以,以JSON格式编写的REST风格的API具有简单、易读、易用的特点。

编写API有什么好处呢?由于API就是把Web App的功能全部封装了,所以,通过API操作数据,可以极大地把前端和后端的代码隔离,使得后端代码易于测试,前端代码编写更简单。

一个API也是一个URL的处理函数,我们希望能直接通过一个@api来把函数变成JSON格式的REST API,这样,获取注册用户可以用一个API实现如下:

@api
@get('/api/users')
def api_get_users():
  users = User.find_by('order by created_at desc')
  # 把用户的口令隐藏掉:
  for u in users:
    u.password = '******'
  return dict(users=users)

所以,@api这个decorator只要编写好了,就可以把任意的URL处理函数变成API调用。

新建一个apis.py,编写@api负责把函数的返回结果序列化为JSON:

def api(func):
  @functools.wraps(func)
  def _wrapper(*args, **kw):
    try:
      r = json.dumps(func(*args, **kw))
    except APIError, e:
      r = json.dumps(dict(error=e.error, data=e.data, message=e.message))
    except Exception, e:
      r = json.dumps(dict(error='internalerror', data=e.__class__.__name__, message=e.message))
    ctx.response.content_type = 'application/json'
    return r
  return _wrapper

@api需要对Error进行处理。我们定义一个APIError,这种Error是指API调用时发生了逻辑错误(比如用户不存在),其他的Error视为Bug,返回的错误代码为internalerror。

客户端调用API时,必须通过错误代码来区分API调用是否成功。错误代码是用来告诉调用者出错的原因。很多API用一个整数表示错误码,这种方式很难维护错误码,客户端拿到错误码还需要查表得知错误信息。更好的方式是用字符串表示错误代码,不需要看文档也能猜到错误原因。

可以在浏览器直接测试API,例如,输入http://localhost:9000/api/users,就可以看到返回的JSON:

Python 相关文章推荐
Python 命令行参数sys.argv
Sep 06 Python
浅谈Django学习migrate和makemigrations的差别
Jan 18 Python
Python程序员面试题 你必须提前准备!(答案及解析)
Jan 23 Python
Python网络编程使用select实现socket全双工异步通信功能示例
Apr 09 Python
深入分析python数据挖掘 Json结构分析
Apr 21 Python
python中datetime模块中strftime/strptime函数的使用
Jul 03 Python
用python实现刷点击率的示例代码
Feb 21 Python
Python使用matplotlib 画矩形的三种方式分析
Oct 31 Python
pytorch对梯度进行可视化进行梯度检查教程
Feb 04 Python
Django serializer优化类视图的实现示例
Jul 16 Python
PyCharm 2020.2.2 x64 下载并安装的详细教程
Oct 15 Python
聊聊Python String型列表求最值的问题
Jan 18 Python
为Python的web框架编写前端模版的教程
Apr 30 #Python
为Python的web框架编写MVC配置来使其运行的教程
Apr 30 #Python
在Python的web框架中配置app的教程
Apr 30 #Python
python实现从ftp服务器下载文件的方法
Apr 30 #Python
简单介绍Python下自己编写web框架的一些要点
Apr 29 #Python
编写Python的web框架中的Model的教程
Apr 29 #Python
python获取本地计算机名字的方法
Apr 29 #Python
You might like
DSP接收机前端设想
2021/03/02 无线电
PHP批量生成缩略图的代码
2008/07/19 PHP
php 验证码实例代码
2010/06/01 PHP
php文件管理基本功能简单操作
2017/01/16 PHP
基于win2003虚拟机中apache服务器的访问
2017/08/01 PHP
jQuery 开天辟地入门篇一
2009/12/09 Javascript
JS实现div内部的文字或图片自动循环滚动代码
2013/04/19 Javascript
基于JavaScript 类的使用详解
2013/05/07 Javascript
javascript获得网页窗口实际大小的示例代码
2013/09/21 Javascript
DOM基础教程之使用DOM设置文本框
2015/01/20 Javascript
javascript操作符"!~"详解
2015/02/10 Javascript
jQuery仿Flash上下翻动的中英文导航菜单实例
2015/03/10 Javascript
javascript生成不重复的随机数
2015/07/17 Javascript
使用CamanJS在Web页面上处理图像的技巧
2015/08/18 Javascript
JavaScript继承学习笔记【新手必看】
2016/05/10 Javascript
关于安卓手机微信浏览器中使用XMLHttpRequest 2上传图片显示字节数为0的解决办法
2016/05/17 Javascript
利用BootStrap的Carousel.js实现轮播图动画效果
2016/12/21 Javascript
html5+CSS 实现禁止IOS长按复制粘贴功能
2016/12/28 Javascript
react-router实现跳转传值的方法示例
2017/05/27 Javascript
Vue插件从封装到发布的完整步骤记录
2019/02/28 Javascript
vue 解决uglifyjs-webpack-plugin打包出现报错的问题
2020/08/04 Javascript
[03:01]DOTA2英雄基础教程 露娜
2014/01/07 DOTA
python实现对一个完整url进行分割的方法
2015/04/29 Python
web.py 十分钟创建简易博客实现代码
2016/04/22 Python
python求最大连续子数组的和
2018/07/07 Python
python bmp转换为jpg 并删除原图的方法
2018/10/25 Python
Django项目使用CircleCI的方法示例
2019/07/14 Python
pandas中的数据去重处理的实现方法
2020/02/10 Python
美国值得信赖的婚恋交友网站:eHarmony
2018/10/04 全球购物
澳大利亚最大的在线美发和美容零售商之一:My Hair Care & Beauty
2019/08/24 全球购物
邀请函的格式
2015/01/30 职场文书
舌尖上的中国观后感
2015/06/02 职场文书
学历证明样本
2015/06/16 职场文书
工商局调档介绍信
2015/10/22 职场文书
大学生,三分钟即兴演讲稿
2019/07/22 职场文书
POST提交数据常见的四种方式
2022/01/18 HTML / CSS