Sanic request 请求数据

Sanic教程 2019-03-21 23:20:12 阅读(10424) 评论(0)

在《Sanic框架介绍》一节中的简单示例中,路由函数test()有一个参数request,它是一个Request对象,包含了客户端(浏览器)发过来的HTTP请求的各类数据。

sanic 请求数据

Sanic Request对象的属性

(1)json :JSON格式数据
当客户端POST来的数据是json格式时,可以通过request.json来访问:

from sanic import response

@app.route('/json', methods=['POST'])
async def post_json(request):
    return response.json({"received": request.json})

(2)args (字典):查询字符串变量

查询字符串变量就是说URL中问号?及其后面的部分,比如,?name=jim&age=12。这样带查询变量的URL被解析后,args字典就是这样的:{'name':['jim'], 'age': ['12']}。request对象的属性query_string就是未解析的字符串值:name=jim&age=12。该属性提供了默认的解析查询变量的策略,稍微我们介绍如何改变解析策略。

from sanic import response

@app.route('/args')
async def args(request):
    return response.json({
        "parsed": True,
        "args": request.args,
        "url": request.url,
        "query_string": request.query_string,
    })


(3)query_args(列表)
该属性提供了另外一种url参数的形式,它是元组(key, value)的列表。该属性提供了默认的解析查询变量的策略,稍微我们介绍如何改变解析策略。

对于前面的URL查询变量?name=jim&age=12,对应的query_args列表就是:
[('name', 'jim'), ('age', '12')]

如果同一个key对应多个value的情况?name=jim&age=12&name=tom,对应的query_args就是:
[('name', 'jim'), ('age', '12'), ('name', 'tom')]

Sanic 18.12 版本已经没有 query_args 这个属性

下面看具体代码来理解args等查询变量:

from sanic import Sanic
from sanic.response import json

app = Sanic()

@app.route('/args')
async def test(request):
    return json({
        "parsed": True,
        "url": request.url,
        "query_string": request.query_string,
        "args": request.args,
        "raw_args": request.raw_args,
        # "query_args": request.query_args,
    })


if __name__ == '__main__':
    app.run(host='127.0.0.1', port=8888)

访问这个web应用的输出是:

{
  "parsed": true,
  "url": "http://127.0.0.1:8888/args?name=jim&age=12&name=tom",
  "query_string": "name=jim&age=12&name=tom",
  "args": {
    "name": [
      "jim",
      "tom"
    ],
    "age": [
      "12"
    ]
  },
  "raw_args": {
    "name": "jim",
    "age": "12"
  }
}

注意 raw_args字典的value不是列表,而是args字典中value的第一个值。这个属性将来会被弃用。

(4)files(字典):拥有name、body和type的文件对象的字典
客户端(浏览器)上传的文件包含在Form data中,files字典的key是Form对象中文件对象的名称(不是文件名),这个文件对象有name(文件名)、body(文件数据)和type(文件类型)三个属性。

from sanic import Sanic
from sanic import response

app = Sanic()

@app.route('/')
async def index(request):
    html = ('<html><body>'
            '<form action="/files" method="post" enctype="multipart/form-data">'
            '<input type="file" name="file1" /> <br />'
            '<input type="file" name="file2" /> <br />'
            '<input type="submit" value="Upload" />'
            '</form>'
            '</body></html>')
    return response.html(html)


@app.route("/files", methods=['POST'])
async def post_json(request):
    test_file = request.files.get('file1')
    file_parameters = {
        'body': len(test_file.body),
        'name': test_file.name,
        'type': test_file.type,
    }

    return response.json({
        "received": True,
        "file_object_names": request.files.keys(),
        "test_file_parameters": file_parameters
    })


if __name__ == '__main__':
    app.run(host='127.0.0.1', port=8888)

运行上面这个web应用,并用浏览器打开http://127.0.0.1:8888/这个地址,可以看到一个简单的上传界面,需要选择两个文件,然后点击“Upload”,就可以看到这个web应用返回的json数据:

// 20190321203852
// http://127.0.0.1:8888/files

{
  "received": true,
  "file_object_names": [
    "file1",
    "file2"
  ],
  "test_file_parameters": {
    "body": 33759,
    "name": "ft-generator.jpg",
    "type": "image/jpeg"
  }
}

注意 从结果可以看出,requests.files.keys()是网页html中inputname,不是文件名。

(5)form(字典):以POST方式传递的form变量
在上面files例子中的网页html部分加一行:

<input type="text" name="title" /> <br />

post_json()函数的返回json里面加上request.form,就可以看到request.form的内容了:

{
  "received": true,
  "form": {
    "title": [
      "猿人学Python"
    ]
  },
  "file_object_names": [
    "file1",
    "file2"
  ],
  "test_file_parameters": {
    "body": 33759,
    "name": "ft-generator.jpg",
    "type": "image/jpeg"
  }
}

(6)body(字节串):POST的原始数据。
这个属性允许我们得到request的原始数据。

(7)headers(字典):包含请求头(headers)的不区分大小写的字典。

(8)method(字符串):HTTP请求的方法,比如GET, POST等。

(9)ip(字符串):客户端(浏览器)的IP地址。

(10)port(字符串):客户端(浏览器)的端口地址。

(11)socket(元组):客户端(浏览器)的(IP, port)

(12)app:正在处理该request的Sanic应用对象的引用。当我们在blueprint文件里面或其它模块需要使用全局的app时可以通过request.app来访问它。

以下都是字符串属性:

(13)url:请求的完整URL。

(14)scheme:请求的URL scheme:httphttps

(15)host:请求的host:127.0.0.1:8888

(16)path:请求的路径path: 比如/files

(17)query_string:请求的查询字符串,name=jim&age=12或空字符串''

(18)uri_template:路由处理器匹配的模板:/posts/<id>/

(19)token 授权header的值,,比如Basic YWRtaW46YWRtaW4=

Sanic Request使用getgetlist访问值

request的属性中是字典的,其实是dict的一个子类RequestParameters。它与内置字典不同的是get()getlist()方法。

  • get(key, default=None)dict的get方法一样。如果value是list时,只返回list的第一个元素。
  • getlist(key, default=None) 返回整个list。
from sanic.request import RequestParameters

args = RequestParameters()
args['titles'] = ['Post 1', 'Post 2']

args.get('titles') # => 'Post 1'

args.getlist('titles') # => ['Post 1', 'Post 2']

总结

request对象是web应用要处理的对象,它包含了客户端(浏览器)的请求数据,通过它的各种属性来访问这些请求数据。

猿人学banner宣传图

我的公众号:猿人学 Python 上会分享更多心得体会,敬请关注。

***版权申明:若没有特殊说明,文章皆是猿人学 yuanrenxue.con 原创,没有猿人学授权,请勿以任何形式转载。***

说点什么吧...