每次客户端请求必需包含完整的信息,REST的六个特性

Restful相关介绍请查看,virtualenv  ,Restful相关介绍请查看,使用python web做Restful 风格,每次客户端请求必需包含完整的信息,很多APP的架构基本上是使用RESTful的形式了,每次客户端请求必需包含完整的信息,很多APP的架构基本上是使用RESTful的形式了,GET|POST|PUT|DELETE|…,curl是很方便的Rest客戶端

图片 16

python 部署 Restful web,pythonrestful

使用python web做Restful
风格,非常粗略,选取Flask框架轻易完成贰个RESTful的劳动。

Restful相关介绍请查看:

使用python web做Restful 风格,很简单,采用Flask框架轻巧完结一个RESTful的服务。

采用python的Flask达成贰个RESTful API服务器端[翻译]

近期近几来,REST已经变为web
services和APIs的标准架构,相当多APP的架构基本上是选用RESTful的款式了。

 

正文将会动用python的Flask框架轻巧完成三个RESTful的服务。

 

REST的七个特色:

 

Client-Server:服务器端与客商端分离。

Stateless(无状态):每一遍客户端央求必需包涵完整的信息,换句话说,每三回呼吁都以单独的。

Cacheable(可缓存):服务器端必得钦点哪些央求是足以缓存的。

Layered
System(分层结构):服务器端与客商端通信必须标准化,服务器的更改并不会潜移暗化顾客端。

Uniform Interface(统一接口):客商端与劳务器端的通信格局必须是联合的。

Code on
demand(按需实行代码?):服务器端可以在内外文中实施代码或然脚本?

Servers can provide executable code or scripts for clients to execute in
their context. This constraint is the only one that is
optional.(没看领会)

 

RESTful web service的样子

 

REST架构正是为了HTTP左券计划的。RESTful web
services的中坚概念是治本能源。能源是由UEvoqueIs来表示,客商端选择HTTP个中的’POST,
OPTIONS, GET, PUT, DELETE’等措施发送央求到服务器,改变相应的财富景况。

 

HTTP央求方法一般也非常方便去叙述操作能源的动作:

 

HTTP方法
动作
例子

GET
获取能源音信

 

(检索订单清单)

 

GET
获取财富音讯

 

(检索订单 #123)

 

POST
创制贰个次的财富

 

(使用带多少的央求,创建贰个新的订单)

 

PUT
更新三个能源

 

(使用带多少的伸手,更新#123订单)

 

DELETE
删除多个财富

 

删去订单#123

 

REST乞求并无需特定的数码格式,常常采用JSON作为必要体,恐怕U宝马X3L的询问参数的一部份。

 

规划三个回顾的web service

 

下边包车型地铁职务将会练习设计以REST准绳为引导,通过分化的央求方法操作能源,标志能源的事例。

 

小编们将写二个To Do List 应用,并且安顿三个web
service。第一步,规划二个根U途达L,比方:

 

 

 

下边包车型大巴URAV4L富含了应用程序的名目、API版本,那是极度有效的,既提供了命名空间的细分,同期又与别的系统区分开来。版本号在晋级新特点时那几个有用,当二个新职能特色扩大在新本子下边时,并不影响旧版本。

 

第二步,规划财富的U奥迪Q5L,那一个例子十二分简易,唯有职分清单。

 

设计如下:

 

HTTP方法
URI
动作

GET
检索职务清单

GET
] 检索多个职责

POST
创立八个新任务

PUT
]
更新几个已存在的任务

DELETE
] 删除三个任务

我们定义任务清单有以下字段:

 

id:独一标记。整型。

title:简短的职责描述。字符串型。

description:完整的义务描述。文本型。

done:职责完结情状。布尔值型。

如上基本做到了设计部份,接下去我们将会达成它!

 

 轻便了解Flask框架

 

Flask好简单,不过又很庞大的Python web 框架。这里有一各类教程Flask
Mega-Tutorial series。(注:Django\Tornado\web.py认为许多框:()

 

在大家深远贯彻web service此前,让大家来轻松地看四个Flask web
应用的组织示例。

 

那边都以在Unix-like(Linux,Mac OS
X)操作系统上面包车型地铁言传身教,可是其余系统也得以跑,比方windows下的Cygwin。只怕命令有个别不相同啊。(注:忽略Windows吧。)

 

先接纳virtualenv安装三个Flask的设想情形。若无安装virtualenv,开拓python必备,最棒去下载安装。

 

 

$ mkdir todo-api

$ cd todo-api

$ virtualenv flask

New python executable in flask/bin/python

Installing setuptools……………………….done.

Installing pip……………….done.

$ flask/bin/pip install flask

 

 那样做好了贰个Flask的开支情状,最早创办三个大致的web应用,在当前目录里面创设三个app.py文件:

 

 

#!flask/bin/python

from flask import Flask

 

app = Flask(__name__)

 

@app.route(‘/’)

def index():

    return “Hello, World!”

 

if __name__ == ‘__main__’:

    app.run(debug=True)

 

去执行app.py:

 

$ chmod a+x app.py

$ ./app.py

 * Running on

 * Restarting with reloader

今后能够展开浏览器,输入

 

好吧,十分差十分的少吗。大家伊始转移到RESTful service!

 

使用Python 和 Flask实现RESTful services

 

采用Flask塑造web services一级轻易。

 

当然,也会有那三个Flask extensions能够协理建构RESTful
services,然则那些例实在太轻巧了,无需动用别的扩大。

 

本条web
service提供扩充,删除、修改职务清单,所以大家必要将任务清单存款和储蓄起来。最简便的做法就是应用Mini的数据库,然则数据库并不是本文涉及太多的。能够参照原来的文章我的全体教程。Flask
Mega-Tutorial series

 

在此间例子大家将职务清单存款和储蓄在内部存款和储蓄器中,那样只好运营在单进度和单线程中,那样是不切合营为生产服务器的,若非就必得使用数据库了。

 

方今大家计划完成率先个web service的入口点:

 

 

#!flask/bin/python

from flask import Flask, jsonify

 

app = Flask(__name__)

 

tasks = [

    {

        ‘id’: 1,

        ‘title’: u’Buy groceries’,

        ‘description’: u’Milk, Cheese, Pizza, Fruit, Tylenol’, 

        ‘done’: False

    },

    {

        ‘id’: 2,

        ‘title’: u’Learn Python’,

        ‘description’: u’Need to find a good Python tutorial on the
web’, 

        ‘done’: False

    }

]

 

@app.route(‘/todo/api/v1.0/tasks’, methods=[‘GET’])

def get_tasks():

    return jsonify({‘tasks’: tasks})

 

if __name__ == ‘__main__’:

    app.run(debug=True)

 

正如您所见,并未有退换太多代码。大家将职责清单存款和储蓄在list内(内部存款和储蓄器),list存放三个非常轻巧的数组字典。每一个实体正是大家地点定义的字段。

 

而 index 入口点有一个get_tasks函数与/todo/api/v1.0/tasks
URI关联,只接受http的GET方法。

 

这几个响应而不是一般文本,是JSON格式的数量,是经过Flask框架的
jsonify模块格式化过的数目。

 

动用浏览器去测量试验web
service并非多个好的艺术,因为要开创分裂类弄的HTTP须求,事实上,我们将使用curl命令行。若无安装curl,快点去安装四个。

 

像刚刚一律运营app.py。

 

开垦两极分化运维以下命令:

 

 

$ curl -i

HTTP/1.0 200 OK

Content-Type: application/json

Content-Length: 294

Server: Werkzeug/0.8.3 Python/2.7.3

Date: Mon, 20 May 2013 04:53:53 GMT

 

{

  “tasks”: [

    {

      “description”: “Milk, Cheese, Pizza, Fruit, Tylenol”,

      “done”: false,

      “id”: 1,

      “title”: “Buy groceries”

    },

    {

      “description”: “Need to find a good Python tutorial on the web”,

      “done”: false,

      “id”: 2,

      “title”: “Learn Python”

    }

  ]

}

 

那样就调用了叁个RESTful service方法!

 

今日,大家写第叁个版本的GET方法获得一定的职分。获取单个职责:

 

 

from flask import abort

 

@app.route(‘/todo/api/v1.0/tasks/<int:task_id>’,
methods=[‘GET’])

def get_task(task_id):

    task = filter(lambda t: t[‘id’] == task_id, tasks)

    if len(task) == 0:

        abort(404)

    return jsonify({‘task’: task[0]})

 

 第3个函数稍稍复杂了有的。义务的id满含在U中华VL内,Flask将task_id参数字传送入了函数内。

 

因此参数,检索tasks数组。倘使参数字传送过来的id一纸空文于数组内,大家须要回到错误代码404,根据HTTP的规定,404表示是”Resource
Not Found”,财富未找到。

 

假如找到任务在内部存款和储蓄器数组内,大家由此jsonify模块将字典打包成JSON格式,并发送响应到客商端上。就像是管理贰个实体字典一样。

 

施行使用curl调用:

 

 

$ curl -i

HTTP/1.0 200 OK

Content-Type: application/json

Content-Length: 151

Server: Werkzeug/0.8.3 Python/2.7.3

Date: Mon, 20 May 2013 05:21:50 GMT

 

{

  “task”: {

    “description”: “Need to find a good Python tutorial on the web”,

    “done”: false,

    “id”: 2,

    “title”: “Learn Python”

  }

}

$ curl -i

HTTP/1.0 404 NOT FOUND

Content-Type: text/html

Content-Length: 238

Server: Werkzeug/0.8.3 Python/2.7.3

Date: Mon, 20 May 2013 05:21:52 GMT

 

<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 3.2 Final//EN”>

<title>404 Not Found</title>

<h1>Not Found</h1>

<p>The requested URL was not found on the
server.</p><p>If you     entered the URL manually please
check your spelling and try again.</p>

 

当我们必要#2
id的能源时,能够取得,不过当我们央求#3的财富时回来了404荒唐。并且重返了一段奇怪的HTML错误,并非咱们期待的JSON,那是因为Flask爆发了私下认可的404响应。顾客端要求吸收的都以JSON的响应,由此我们必要革新404错误管理:

 

from flask import make_response

 

@app.errorhandler(404)

def not_found(error):

    return make_response(jsonify({‘error’: ‘Not found’}), 404)

如此这般我们就获取了友好的API错误响应:

 

 

$ curl -i

HTTP/1.0 404 NOT FOUND

Content-Type: application/json

Content-Length: 26

Server: Werkzeug/0.8.3 Python/2.7.3

Date: Mon, 20 May 2013 05:36:54 GMT

 

{

  “error”: “Not found”

}

 

接下去大家兑现 POST 方法,插入八个新的天职到数组中:

 

 

from flask import request

 

@app.route(‘/todo/api/v1.0/tasks’, methods=[‘POST’])

def create_task():

    if not request.json or not ‘title’ in request.json:

        abort(400)

    task = {

        ‘id’: tasks[-1][‘id’] + 1,

        ‘title’: request.json[‘title’],

        ‘description’: request.json.get(‘description’, “”),

        ‘done’: False

    }

    tasks.append(task)

    return jsonify({‘task’: task}), 201

 

 request.json里面含有呼吁数据,假使不是JSON可能个中未有包涵title字段,将会回去400的错误代码。

 

当创造一个新的职务字典,使用最终三个职责id数值加1作为新的职分id(最简易的办法产生一个独一字段)。这里允许不带description字段,暗中认可将done字段值为False。

 

将新任务叠合到tasks数组里面,而且再次回到客商端201状态码和刚刚增加的天职内容。HTTP定义了201状态码为“Created”。

 

测验上面的新成效:

 

 

$ curl -i -H “Content-Type: application/json” -X POST -d ‘{“title”:”Read
a book”}’

HTTP/1.0 201 Created

Content-Type: application/json

Content-Length: 104

Server: Werkzeug/0.8.3 Python/2.7.3

Date: Mon, 20 May 2013 05:56:21 GMT

 

{

  “task”: {

    “description”: “”,

    “done”: false,

    “id”: 3,

    “title”: “Read a book”

  }

}

 

在意:借使利用原生版本的curl命令行提醒符,上边包车型地铁命令会正确执行。假设是在Windows下使用Cygwin
bash版本的curl,需求将body部份增添双引号:

 

curl -i -H “Content-Type: application/json” -X POST -d
“{“””title”””:”””Read a book”””}”

多数在Windows中须要选拔双引号富含body部份在内,何况亟需多个双引号转义体系。

 

完了地方的业务,就足以看出更新之后的list数组内容:

 

$ curl -i

HTTP/1.0 200 OK

Content-Type: application/json

Content-Length: 423

Server: Werkzeug/0.8.3 Python/2.7.3

Date: Mon, 20 May 2013 05:57:44 GMT

 

{

  “tasks”: [

    {

      “description”: “Milk, Cheese, Pizza, Fruit, Tylenol”,

      “done”: false,

      “id”: 1,

      “title”: “Buy groceries”

    },

    {

      “description”: “Need to find a good Python tutorial on the web”,

      “done”: false,

      “id”: 2,

      “title”: “Learn Python”

    },

    {

      “description”: “”,

      “done”: false,

      “id”: 3,

      “title”: “Read a book”

    }

  ]

}

 

余下的七个函数如下:

 

 

@app.route(‘/todo/api/v1.0/tasks/<int:task_id>’,
methods=[‘PUT’])

def update_task(task_id):

    task = filter(lambda t: t[‘id’] == task_id, tasks)

    if len(task) == 0:

        abort(404)

    if not request.json:

        abort(400)

    if ‘title’ in request.json and type(request.json[‘title’]) !=
unicode:

        abort(400)

    if ‘description’ in request.json and
type(request.json[‘description’]) is not unicode:

        abort(400)

    if ‘done’ in request.json and type(request.json[‘done’]) is not
bool:

        abort(400)

    task[0][‘title’] = request.json.get(‘title’,
task[0][‘title’])

    task[0][‘description’] = request.json.get(‘description’,
task[0][‘description’])

    task[0][‘done’] = request.json.get(‘done’, task[0][‘done’])

    return jsonify({‘task’: task[0]})

 

@app.route(‘/todo/api/v1.0/tasks/<int:task_id>’,
methods=[‘DELETE’])

def delete_task(task_id):

    task = filter(lambda t: t[‘id’] == task_id, tasks)

    if len(task) == 0:

        abort(404)

    tasks.remove(task[0])

    return jsonify({‘result’: True})

 

delete_task函数没什么太极度的。update_task函数必要检讨所输入的参数,防止发生错误的bug。确保是意料的JSON格式写入数据Curry面。

 

测量试验将职分#2的done字段改动为done状态:

 

 

$ curl -i -H “Content-Type: application/json” -X PUT -d ‘{“done”:true}’

HTTP/1.0 200 OK

Content-Type: application/json

Content-Length: 170

Server: Werkzeug/0.8.3 Python/2.7.3

Date: Mon, 20 May 2013 07:10:16 GMT

 

{

  “task”: [

    {

      “description”: “Need to find a good Python tutorial on the web”,

      “done”: true,

      “id”: 2,

      “title”: “Learn Python”

    }

  ]

}

 

改进Web Service接口

 

此时此刻大家还应该有三个难点,顾客端有十分的大恐怕需求从再次回到的JSON中重复布局UTucsonI,即使明日加盟新的性猪时,大概须求修改顾客端。(比方新增添版本。)

 

咱俩得以回到整个UQashqaiI的渠道给客商端,并非天职的id。为了这些职能,创造贰个小函数生成叁个“public”版本的任务U本田CR-VI重临:

 

 

from flask import url_for

 

def make_public_task(task):

    new_task = {}

    for field in task:

        if field == ‘id’:

            new_task[‘uri’] = url_for(‘get_task’,
task_id=task[‘id’], _external=True)

        else:

            new_task[field] = task[field]

    return new_task

 

通过Flask的url_for模块,获取任务时,将任务中的id字段替换到uri字段,何况把值改为uri值。

 

当大家回去包涵职分的list时,通过那一个函数处理后,重回完整的uri给顾客端:

 

@app.route(‘/todo/api/v1.0/tasks’, methods=[‘GET’])

def get_tasks():

    return jsonify({‘tasks’: map(make_public_task, tasks)})

到现在收看的搜寻结果:

 

 

$ curl -i

HTTP/1.0 200 OK

Content-Type: application/json

Content-Length: 406

Server: Werkzeug/0.8.3 Python/2.7.3

Date: Mon, 20 May 2013 18:16:28 GMT

 

{

  “tasks”: [

    {

      “title”: “Buy groceries”,

      “done”: false,

      “description”: “Milk, Cheese, Pizza, Fruit, Tylenol”,

      “uri”: “”

    },

    {

      “title”: “Learn Python”,

      “done”: false,

      “description”: “Need to find a good Python tutorial on the web”,

      “uri”: “”

    }

  ]

}

 

这种措施避免了与别的功效的同盟,得到的是欧洲经济共同体uri并非一个id。

 

RESTful web service的平安认证

 

大家已经产生了整个职能,可是咱们还或者有一个难点。web
service任何人都能够访问的,那不是多少个好主意。

 

当前service是兼具顾客端都足以接连的,若是有外人理解了这么些API就足以写个顾客端随便退换数据了。
大好多课程未有与乌兰察布相关的内容,那是个非常严重的标题。

 

最简便易行的艺术是在web
service中,只同意客商名和密码验证通过的客商端连接。在多个好端端的web应用中,应该有记名表单提交去印证,同期服务器会成立三个会话进度去开展报纸发表。那几个会话进程id会被存放在客商端的cookie里面。也才那样就违返了小编们REST中无状态的条条框框,因而,大家必要客商端每趟都将他们的验证音信发送到服务器。

 

 为此大家有二种方法表单认证方法去做,分别是 Basic 和 Digest。

 

这里有有个小Flask extension能够轻易做到。首先须求设置 Flask-HTTPAuth :

 

$ flask/bin/pip install flask-httpauth

若是web service只有顾客 ok 和密码为 python
的客户接入。上边就安装了三个Basic HTTP认证:

 

 

from flask.ext.httpauth import HTTPBasicAuth

auth = HTTPBasicAuth()

 

@auth.get_password

def get_password(username):

    if username == ‘ok’:

        return ‘python’

    return None

 

@auth.error_handler

def unauthorized():

    return make_response(jsonify({‘error’: ‘Unauthorized access’}),
401)

 

get_password函数是一个回调函数,获取一个已知客户的密码。在目不暇接的连串中,函数是索要到数据库中检查的,然则此地只是一个小示例。

 

当发生认证错误之后,error_handler回调函数会发送错误的代码给客商端。这里大家自定义三个错误代码401,再次回到JSON数据,并不是HTML。

 

将@auth.login_required装饰器加多到要求表明的函数方面:

 

@app.route(‘/todo/api/v1.0/tasks’, methods=[‘GET’])

@auth.login_required

def get_tasks():

    return jsonify({‘tasks’: tasks})

于今,试试使用curl调用这些函数:

 

 

$ curl -i

HTTP/1.0 401 UNAUTHORIZED

div>Content-Type: application/json

近来近些年,REST已经济体改成web
services和APIs的正规架构,非常多应用程式的架构基本上是应用RESTful的形式了。

大家好,作者是IT修真院尼科西亚分院第01期学员,一枚正直纯洁善良的web程序员。明天给大家大快朵颐一下,修真院官方网站JAVA职分2的知识点——Curl发送HTTP乞请。

1. 条件搭建

先是需求防微杜渐条件

  need virtualenv  python的沙盒情况–virtualenv

    这里运用 virtualenv
 来创建一个Python碰到,用来运作我们稍后的restful服务端。

  need flask

Restful相关介绍请查看:

 

在linux上有两种接口测量检验工具,如restclient,httpie,ab等,在档次中最常用的是curl,用来进展轻便的测验。

1.1 安装

1. 情况搭建

首先要求预备条件

  need
virtualenv  python的沙盒情形–virtualenv (不必须)

    这里运用 virtualenv
 来创立三个Python情状,用来运行大家稍后的restful服务端。

  need flask (必须)

本文将会选拔python的Flask框架轻易落成三个RESTful的劳务。

curl是很有益于的Rest客戶端,能够很有利的产生許多Rest
API测量试验的急需,利用curl指令,能够送出HTTP GET, POST, PUT, DELETE,
也足以改换 HTTP header来知足使用REST API供给的特定条件。

1.1.1 pip

  下载地址:

  下载 pip tar.gz

  解压 tar -xzvf 

  进入目录安装 python setup.py install 就可以使用

1.1 安装

 

-X/–request [GET|POST|PUT|DELETE|…] 使用钦点的HTTP method
发出钦命的request

1.1.2 virtualenv  

  pip install virtualenv 间接下载安装

  或者 进入  下载 tar包
和pip安装类似

1.1.1 pip 

  安装软件用

  下载地址:

  下载 pip tar.gz

  解压 tar -xzvf 

  步入目录安装 python setup.py install 就能够使用

REST的多少个天性:

-H/–header “XX:XXX” 设定request的header

1.1.3 flask

  pip install flask 直接下载安装

  或者  下载tar包
解压安装

  手动装供给(install会自动安装,假如linux设想机未联网,依据提示缺什么,去安装什么):

    click >=2.0:

    itsdangerous
>=0.21:

    jinja2 >= 2.4:

    werkzeug>=0.7:

1.1.2 virtualenv  

  创制设想意况用

  pip install virtualenv 直接下载安装

  或者 进入  下载 tar包
和pip安装类似

 

-i/–include 显示response的header

2. 条件测量检验

1.1.3 flask

  web框架 重要

  pip install flask 直接下载安装

  或者  下载tar包
解压安装

  手动装供给(install会自动安装,若是linux虚构机未联网,依据提醒缺什么,去安装什么):

    click >=2.0:

    itsdangerous
>=0.21:

    jinja2 >= 2.4:

    werkzeug>=0.7:

Client-Server:服务器端与客商端分离。

-d/–data “XX=XXX” 设定HTTP parameters

2.1 创立设想碰到

选料四个恰到好处的门道下 

自己选取的是  /var/flask 当然能够任意挑选贰个索引

virtualenv web ,做四个名字为web的python景况

目录如:

  图片 1

2. 条件测验

Stateless(无状态):每次客商端央求必得富含完整的新闻,换句话说,每叁回呼吁都是独自的。

-v/–verbose 输出相当多的音讯

2.2 新建app.py

在bin中新建app.py

app.route 的用法和Springmvc 的controller
requestmapping很周边,详细请查看:

#环境测试
from flask import Flask

app = Flask(__name__)

@app.route('/')
def index():
    return "Hello, Python Flask!"

if __name__ == '__main__':
    app.run(debug=True)

2.1 创设设想境况

分选一个十分的门径下 

本人选用的是  /var/flask 当然能够随意选拔叁个目录

virtualenv web
,做贰个名叫web的python情状,也能够绝不那个景况,直接第二步创建app.py

目录如:

  图片 2

Cacheable(可缓存):服务器端必须钦点哪些央求是可以缓存的。

-u/–user “XX:XXX” 使用者帐密

2.3 实施采访

执行 python app.py

  图片 3

本土访问(可以新开三个ssh进行测量检验,也足以用IP地址 用浏览器测量检验)

这里运用linux内部访问:curl -i

  图片 4

拜会获得了Hello, Python Flask!

申明条件搭建成功success!。

2.2 新建app.py

在bin中新建app.py

app.route 的用法和Springmvc 的controller
requestmapping很周围,详细请查看:

#环境测试
from flask import Flask

app = Flask(__name__)

@app.route('/')
def index():
    return "Hello, Python Flask!"

if __name__ == '__main__':
    app.run(host="0.0.0.0",debug=True)

Layered
System(分层结构):服务器端与顾客端通信必须规范化,服务器的更换并不会影响顾客端。

-b/–cookie cookie文件路线 使用cookie

3. 正式职业

这里仍旧选用Person对象来做Restful的示范,参考:SpringMVC 构建Restful风格
及难题管理

/persons  GET         得所有person

/person/{id}  GET     得到id的person

/person   POST        新增person

/person/{id}  PUT      更新id的person

/person/{id}  DELETE    删除id的person

新建person.py

编码:

#coding=utf-8

引进供给的模块:

from flask import Flask,jsonify,abort,make_response,request

效仿数据库数据:

#模拟数据库 person 属性 id name age done url
persons = [
    {
        'id': 1,
        'name': u'loveincode',
        'age': 20, 
        'done': False,
        'url':u'loveincode.cnblogs.com'
    },
    {
        'id': 2,
        'name': u'strive',
        'age': 18, 
        'done': False,
        'url':u'loveincode.cnblogs.com'
    }
]

2.3 实行访谈

执行 python app.py

  图片 5

本地访谈(可以新开一个ssh举行测量检验,也足以用IP地址(ip访谈供给绑定0.0.0.0)
 app.run(host=”0.0.0.0″,debug=True)
 
用浏览器测验)

此间运用linux内部访问:curl -i

  图片 6

访问获得了Hello, Python
Flask!

注脚意况搭建成功success!。

Uniform Interface(统一接口):顾客端与劳动器端的简报形式必须是统一的。

-X后面加HTTP method,如:curl -X [GET|POST|PUT|DELETE]
“”
(纯丹麦语、数字并不是加引号,其余情形不加引号恐怕会出题目)

3.1 GET persons

代码设计:

@app.route('/restful/persons', methods=['GET'])
def get_persons():
    return jsonify({'persons': persons})

先执行:python person.py

test:curl -i

  图片 7

3. 标准工作

此间依然利用Person对象来做Restful的言传身教,仿效:SpringMVC
构建Restful风格
及难题管理

/persons  GET         得所有person

/person/{id}  GET     得到id的person

/person   POST        新增person

/person/{id}  PUT      更新id的person

/person/{id}  DELETE    删除id的person

新建person.py

编码:

#coding=utf-8

引进须求的模块:

from flask import Flask,jsonify,abort,make_response,request

仿照数据库数据:

#模拟数据库 person 属性 id name age done url
persons = [
    {
        'id': 1,
        'name': u'loveincode',
        'age': 20, 
        'done': False,
        'url':u'loveincode.cnblogs.com'
    },
    {
        'id': 2,
        'name': u'strive',
        'age': 18, 
        'done': False,
        'url':u'loveincode.cnblogs.com'
    }
]

Code on
demand(按需实践代码?):服务器端能够在左右文中施行代码或然脚本?

1)设置header:curl -i -H “Content-Type: application/json”

3.2 GET person

@app.route('/restful/person/<int:id>', methods=['GET'])
def get_person(id):
    person = filter(lambda t: t['id'] == id, persons)
    if len(person) == 0:
        abort(404)
    return jsonify({'person': person[0]})

先执行:python person.py

test:curl -i

  图片 8

错误404 后边一同讲。

3.1 GET persons

代码设计:

@app.route('/restful/persons', methods=['GET'])
def get_persons():
    return jsonify({'persons': persons})

先执行:python person.py

test:curl -i

  图片 9

Servers can provide executable code or scripts for clients to execute in
their context. This constraint is the only one that is
optional.(没看通晓)

2)设置HTTP parameter:curl -X POST -d “param1=value1¶m2=value2” 或者 -d
“param1=value1” -d “param2=value2”

3.3 POST

@app.route('/restful/person', methods=['POST'])
def create_person():
    if not request.json or not 'name' in request.json:
        abort(400)
    person = {
        'id': persons[-1]['id'] + 1,
        'name': request.json['name'],
        #如果没有提交age参数默认为20
        'age': request.json.get('age', 20),
        #同理如果没提交url,url也是默认值
        'url': request.json.get('url', "默认URL loveincode.cnblogs.com"),
        #该参数初始化FALSE
        'done': False
    }
    persons.append(person)
    return jsonify({'person': person}), 201

先执行:python person.py

test:提供多个测验

curl -i -H “Content-Type: application/json” -X POST -d ‘{“name”:”new
loveincode”}’

curl -i -H “Content-Type: application/json” -X POST -d ‘{“name”:”new
loveincode”,”age”:23}’

curl -i -H “Content-Type: application/json” -X POST -d ‘{“name”:”new
loveincode”,”age”:23,”url”:”1234″}’

证实最后三个 ,先post 再看有着 增多成功

  图片 10

3.2 GET person

@app.route('/restful/person/<int:id>', methods=['GET'])
def get_person(id):
    person = filter(lambda t: t['id'] == id, persons)
    if len(person) == 0:
        abort(404)
    return jsonify({'person': person[0]})

先执行:python person.py

test:curl -i

  图片 11

不当404 后边一齐讲。

 

3)session认证:curl -X GET ” –header
‘sessionid:1234567890987654321’

3.4 PUT

@app.route('/restful/person/<int:id>', methods=['PUT'])
def update_person(id):
    person = filter(lambda t: t['id'] == id, persons)
    if len(person) == 0:
        abort(404)
    if not request.json:
        abort(400)
    if 'name' in request.json and type(request.json['name']) != unicode:
        abort(400)
    if 'age' in request.json and type(request.json['age']) is not int:
        abort(400)
    if 'url' in request.json and type(request.json['url']) != unicode:
        abort(400)
    if 'done' in request.json and type(request.json['done']) is not bool:
        abort(400)
    person[0]['name'] = request.json.get('name', person[0]['name'])
    person[0]['age'] = request.json.get('age', person[0]['age'])
    person[0]['url'] = request.json.get('url', person[0]['url'])
    person[0]['done'] = request.json.get('done', person[0]['done'])
    return jsonify({'person': person[0]})

先执行:python person.py

test:

curl -i -H “Content-Type: application/json” -X PUT -d ‘{“done”:true}’

curl -i -H “Content-Type: application/json” -X PUT -d
‘{“name”:”update”,”age”:30}’

  图片 12

3.3 POST

@app.route('/restful/person', methods=['POST'])
def create_person():
    if not request.json or not 'name' in request.json:
        abort(400)
    person = {
        'id': persons[-1]['id'] + 1,
        'name': request.json['name'],
        #如果没有提交age参数默认为20
        'age': request.json.get('age', 20),
        #同理如果没提交url,url也是默认值
        'url': request.json.get('url', "默认URL loveincode.cnblogs.com"),
        #该参数初始化FALSE
        'done': False
    }
    persons.append(person)
    return jsonify({'person': person}), 201

先执行:python person.py

test:提供多个测量检验

curl -i -H “Content-Type:
application/json” -X POST -d ‘{“name”:”new loveincode”}’

curl -i -H “Content-Type:
application/json” -X POST -d ‘{“name”:”new loveincode”,”age”:23}’

curl -i -H “Content-Type:
application/json” -X POST -d ‘{“name”:”new
loveincode”,”age”:23,”url”:”1234″}’

表明最终贰个 ,先post 再看有着 增添成功

  图片 13

RESTful web service的样子

4) 使用cookie:curl -i –header “Accept:application/json” -X GET -b
~/cookie.txt

3.5 DELETE

@app.route('/restful/person/<int:id>', methods=['DELETE'])
def delete_person(id):
    person = filter(lambda t: t['id'] == id, persons)
    if len(person) == 0:
        abort(404)
    persons.remove(person[0])
    return jsonify({'result': True})

先执行:python person.py

test:

curl -i -X DELETE

  图片 14

3.4 PUT

@app.route('/restful/person/<int:id>', methods=['PUT'])
def update_person(id):
    person = filter(lambda t: t['id'] == id, persons)
    if len(person) == 0:
        abort(404)
    if not request.json:
        abort(400)
    if 'name' in request.json and type(request.json['name']) != unicode:
        abort(400)
    if 'age' in request.json and type(request.json['age']) is not int:
        abort(400)
    if 'url' in request.json and type(request.json['url']) != unicode:
        abort(400)
    if 'done' in request.json and type(request.json['done']) is not bool:
        abort(400)
    person[0]['name'] = request.json.get('name', person[0]['name'])
    person[0]['age'] = request.json.get('age', person[0]['age'])
    person[0]['url'] = request.json.get('url', person[0]['url'])
    person[0]['done'] = request.json.get('done', person[0]['done'])
    return jsonify({'person': person[0]})

先执行:python person.py

test:

curl -i -H “Content-Type:
application/json” -X PUT -d ‘{“done”:true}’

curl -i -H “Content-Type:
application/json” -X PUT -d ‘{“name”:”update”,”age”:30}’

  图片 15

 

5) 文件上传:curl -i -X POST -F ‘file=@/User/my_file.txt’ -F
‘name=file_name’

3.6 Error 处理

对400 和 404 举行不当json封装,三个和好的荒唐提醒

@app.errorhandler(404)
def not_found(error):
    return make_response(jsonify({'error': 'Not found'}), 404)

@app.errorhandler(400)
def not_found(error):
    return make_response(jsonify({'error': 'Request Error'}), 400)

github地址:

参考:

铺排 Restful web,pythonrestful 使用python
web做Restful 风格,极粗略,选择Flask框架轻便达成二个RESTful的劳动。
Restful相关介绍请查看:http…

3.5 DELETE

@app.route('/restful/person/<int:id>', methods=['DELETE'])
def delete_person(id):
    person = filter(lambda t: t['id'] == id, persons)
    if len(person) == 0:
        abort(404)
    persons.remove(person[0])
    return jsonify({'result': True})

先执行:python person.py

test:

curl -i -X DELETE

  图片 16

REST架构正是为了HTTP公约布置的。RESTful web
services的基本概念是管理财富。能源是由URubiconIs来代表,客商端选择HTTP个中的’POST,
OPTIONS, GET, PUT, DELETE’等措施发送央求到服务器,改换相应的财富景况。

6) HTTP基本注解(HTTP Basic Authentication):curl -i –user
username:password ‘

3.6 Error 处理

对400 和 404 进行不当json封装,三个投机的荒谬提醒

@app.errorhandler(404)
def not_found(error):
    return make_response(jsonify({'error': 'Not found'}), 404)

@app.errorhandler(400)
def not_found(error):
    return make_response(jsonify({'error': 'Request Error'}), 400)

github地址:

参考:

 

wget命令用来从内定的U奥迪Q3L下载文件,访谈接口时回来的数据会保存到本地。(自个儿测量试验能够访谈GET和POST接口)

HTTP伏乞方法一般也格外得体去陈说操作财富的动作:

例:wget

 

wget –post-data=”xx=xxx”

HTTP方法
动作
例子

实际上运用

GET
获取财富音信

在服务器上运转curl命令,加上url和有关参数

curl发送POST央求时,数据能够行使xml格式或json格式,
並且能够发送本地的json和xml文件。

 

1) curl -H ‘content-type: application/json’ -X POST -d
‘{“name”:”shfbjsf”}’

(检索订单清单)

2) curl -X POST -H ‘content-type: application/json’ -d
@/apps/jsonfile.json

 

3) curl -H ‘content-type: application/xml’ -X POST -d ‘<?xml
version=”1.0″ encoding=”UTF-8″?><name>aaa</name>’

GET
获取资讯

4) curl -X POST -H ‘content-type: application/json’ -d
@/apps/xmlfile.json

参照一:使用curl指令测验rest

 

参照二:使用curl进行接口测量试验

(检索订单 #123)

利用restclient,httpie,ab等工具测量试验rest

 

PPT链接

POST
创造一个次的能源

Curl发送HTTP请求_Tencent录像

提问:curl需要在linux安装吗?

 

答:curl时linux系统命令,无需设置。

(使用带多少的伸手,创制八个新的订单)

咨询:有postman了怎么还要用curl或weget测量检验接口呢?

 

答:postman在多少景况下是不佳用的,例如服务器限制内网访谈,这一年用curl更方便人民群众。

PUT
更新叁个财富

叩问:rest顾客端是怎么?

答:rest顾客端是指能够发送rest央浼的顾客端工具,如restclient,postman等,都属于rest客商端。

 

鸣谢

(使用带多少的伸手,更新#123订单)

感激大家看来

 


DELETE
删除三个能源

前日的分享就到此地呀,接待我们点赞、转发、留言、拍砖~

 

除去订单#123

 

REST央求并不供给特定的数额格式,经常使用JSON作为诉求体,可能UEscortL的询问参数的一部份。

 

安顿贰个轻巧的web service

 

上边的任务将会演习设计以REST法则为引导,通过不相同的诉求方法操作能源,标志财富的事例。

 

大家将写三个To Do List 应用,並且安顿三个web
service。第一步,规划二个根URubiconL,举个例子:

 

 

 

地点的U传祺L包罗了应用程序的名号、API版本,那是充裕使得的,既提供了命名空间的细分,同一时候又与其余系统有别于开来。版本号在进级新特征时卓殊有用,当贰个新职能特色增添在新本子上面时,并不影响旧版本。

 

其次步,规划财富的UPAJEROL,这些例子拾分归纳,唯有任务清单。

 

布置如下:

 

HTTP方法
URI
动作

GET
检索职分清单

GET
] 检索一个职分

POST
创造一个新职务

PUT
]
更新一个已存在的任务

DELETE
] 删除贰个职务

大家定义职分清单有以下字段:

 

id:唯一标志。整型。

title:简短的职分描述。字符串型。

description:完整的职分描述。文本型。

done:任务成功境况。布尔值型。

如上基本实现了布署部份,接下去我们将会兑现它!

 

 简单掌握Flask框架

 

Flask好简单,不过又很强劲的Python
web 框架。这里有一密密麻麻教程Flask Mega-Tutorial
series。(注:Django\Tornado\web.py感到好些个框:()

 

在我们深刻贯彻web service在此以前,让大家来轻巧地看二个Flask web
应用的布局示例。

 

此处都以在Unix-like(Linux,Mac OS
X)操作系统上边包车型客车亲自去做,不过其余系统也足以跑,比如windows下的Cygwin。恐怕命令有个别差别呢。(注:忽略Windows吧。)

 

先选择virtualenv安装多个Flask的虚构蒙受。若无安装virtualenv,开辟python必备,最佳去下载安装。

 

 

$ mkdir todo-api

$ cd todo-api

$ virtualenv flask

New python executable in flask/bin/python

Installing setuptools……………………….done.

Installing pip……………….done.

$ flask/bin/pip install flask

 

 那样做好了多个Flask的支出条件,伊始创立四个粗略的web应用,在当前目录里面创设二个app.py文件:

 

 

#!flask/bin/python

from flask import Flask

 

app = Flask(__name__)

 

@app.route(‘/’)

def index():

    return “Hello, World!”

 

if __name__ == ‘__main__’:

    app.run(debug=True)

 

去执行app.py: