用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入门者的一些编程建议
Jun 15 Python
win10系统中安装scrapy-1.1
Jul 03 Python
Python3下错误AttributeError: ‘dict’ object has no attribute’iteritems‘的分析与解决
Jul 06 Python
Python编程之string相关操作实例详解
Jul 22 Python
Python实现小数转化为百分数的格式化输出方法示例
Sep 20 Python
Python编程使用NLTK进行自然语言处理详解
Nov 16 Python
Python实现通讯录功能
Feb 22 Python
Flask-Mail用法实例分析
Jul 21 Python
Python批处理更改文件名os.rename的方法
Oct 26 Python
利用ctypes获取numpy数组的指针方法
Feb 12 Python
python try except返回异常的信息字符串代码实例
Aug 15 Python
python用700行代码实现http客户端
Jan 14 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
深入PHP获取随机数字和字母的方法详解
2013/06/06 PHP
php输出1000以内质数(素数)示例
2014/02/16 PHP
PHP解码unicode编码的中文字符代码分享
2014/08/13 PHP
JavaScript高级程序设计(第3版)学习笔记12 js正则表达式
2012/10/11 Javascript
不用构造函数(Constructor)new关键字也能实现JavaScript的面向对象
2013/01/11 Javascript
判断浏览器的内核及版本号方法汇总
2015/01/05 Javascript
js命名空间写法示例
2015/12/18 Javascript
JS中Eval解析JSON字符串的一个小问题
2016/02/21 Javascript
Angular 中 select指令用法详解
2016/09/29 Javascript
Javascript中作用域的详细介绍
2016/10/06 Javascript
JS控制FileUpload的上传文件类型实例代码
2016/10/07 Javascript
JS数组排序方法实例分析
2016/12/16 Javascript
详解微信小程序开发—你期待的分享功能来了,微信小程序序新增5大功能
2016/12/23 Javascript
Vue.js -- 过滤器使用总结
2017/02/18 Javascript
详解基于webpack和vue.js搭建开发环境
2017/04/05 Javascript
vue 里面使用axios 和封装的示例代码
2017/09/01 Javascript
微信小程序调用摄像头隐藏式拍照功能
2018/08/22 Javascript
javascript数组去重方法总结(推荐)
2019/03/20 Javascript
深入浅出 Vue 系列 -- 数据劫持实现原理
2019/04/23 Javascript
Python自动化运维和部署项目工具Fabric使用实例
2016/09/18 Python
浅析使用Python操作文件
2017/07/31 Python
详解Python 序列化Serialize 和 反序列化Deserialize
2017/08/20 Python
Python3学习笔记之列表方法示例详解
2017/10/06 Python
Python3使用正则表达式爬取内涵段子示例
2018/04/22 Python
Python 常用模块 re 使用方法详解
2019/06/06 Python
基于python-opencv3的图像显示和保存操作
2019/06/27 Python
将python运行结果保存至本地文件中的示例讲解
2019/07/11 Python
python实现文件的分割与合并
2019/08/29 Python
Html5游戏开发之乒乓Ping Pong游戏示例(二)
2013/01/21 HTML / CSS
IRO美国官网:法国服装品牌
2018/03/06 全球购物
初三班主任寄语大全
2014/04/04 职场文书
岗位竞聘演讲稿范文
2014/04/24 职场文书
孩子满月酒答谢词
2015/09/30 职场文书
2015年党务工作者个人工作总结
2015/10/22 职场文书
2016年“5.12”护士节慰问信
2015/11/30 职场文书
浅谈mysql返回Boolean类型的几种情况
2021/06/04 MySQL