Sanic 中文文档: Python 高性能 web 框架 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
markjack
V2EX    Python

Sanic 中文文档: Python 高性能 web 框架

  •  
  •   markjack 2017-10-31 11:53:32 +08:00 11546 次点击
    这是一个创建于 2952 天前的主题,其中的信息可能已经有所发展或是发生改变。

    入门指南

    • Install Sanic:python3 -m pip install sanic

    example

    from sanic import Sanic from sanic.response import text app = Sanic(name) @app.route(“/“) async def test(request): return text(‘ Hello world!’) app.run(host=” 0.0.0.0 ”, port=8000, debug=True) 

    路由

    • 路由允许用户为不同的 URL 端点指定处理程序函数。

    demo:

    from sanic.response import json @app.route(“/“) async def test(request): return json({ “ hello ”: “ world ” }) 
    • url http://server.url/被访问(服务器的基本 url),最终'/'被路由器匹配到处理程序函数,测试,然后返回一个 JSON 对象。

    Request parameters (请求参数)

    • 要指定一个参数,可以用像这样的角引号<param>包围它。请求参数将作为关键字参数传递给路线处理程序函数。

    demo

    from sanic.response import text @app.route(‘/tag/<tag>‘) async def tag_handler(request, tag): return text(‘ Tag - {}’.format(tag)) 
    • 为参数指定类型,在参数名后面添加(:类型)。如果参数不匹配指定的类型,Sanic 将抛出一个不存在的异常,导致一个 404 页面

    demo:

    from sanic.response import text @app.route(‘/number/<integer_arg:int>‘) async def integer_handler(request, integer_arg): return text(‘ Integer - {}’.format(integer_arg)) @app.route(‘/number/<number_arg:number>‘) async def number_handler(request, number_arg): return text(‘ Number - {}’.format(number_arg)) @app.route(‘/person/<name:[A-z]+>‘) async def person_handler(request, name): return text(‘ Person - {}’.format(name)) @app.route(‘/folder/<folder_id:[A-z0-9]{0,4}>‘) async def folder_handler(request, folder_id): return text(‘ Folder - {}’.format(folder_id)) 

    HTTP request types(请求类型)

    • 路由装饰器接受一个可选的参数,方法,它允许处理程序函数与列表中的任何 HTTP 方法一起工作。

    demo_1

    from sanic.response import text @app.route(‘/post ’, methods=[‘ POST ’]) async def post_handler(request): return text(‘ POST request - {}’.format(request.json)) @app.route(‘/get ’, methods=[‘ GET ’]) async def get_handler(request): return text(‘ GET request - {}’.format(request.args)) 

    demo_2

    from sanic.response import text @app.post(‘/post ’) async def post_handler(request): return text(‘ POST request - {}’.format(request.json)) @app.get(‘/get ’) async def get_handler(request): return text(‘ GET request - {}’.format(request.args)) 

    add_route method(增加路由)

    from sanic.response import text # Define the handler functions async def handler1(request): return text('OK') async def handler2(request, name): return text('Folder - {}'.format(name)) async def person_handler2(request, name): return text('Person - {}'.format(name)) # Add each handler function as a route app.add_route(handler1, '/test') app.add_route(handler2, '/folder/<name>') app.add_route(person_handler2, '/person/<name:[A-z]>', methods=['GET']) 

    url_for

    • Sanic 提供了一个 urlfor 方法,根据处理程序方法名生成 url。避免硬编码 url 路径到您的应用程序

    demo

    @app.route('/') async def index(request): # generate a URL for the endpoint `post_handler` url = app.url_for('post_handler', post_id=5) # the URL is `/posts/5`, redirect to it return redirect(url) @app.route('/posts/<post_id>') async def post_handler(request, post_id): return text('Post - {}'.format(post_id)) 

    注意:

    • 给 url equest 的关键字参数不是请求参数,它将包含在 URL 的查询字符串中。例如:
    url = app.url_for('post_handler', post_id=5, arg_One='one', arg_two='two') #/posts/5?arg_One=one&arg_two=two 
    • 所有有效的参数必须传递给 url 以便构建一个 URL。如果没有提供一个参数,或者一个参数与指定的类型不匹配,就会抛出一个 URLBuildError 可以将多值参数传递给 url
    url = app.url_for('post_handler', post_id=5, arg_One=['one', 'two']) # /posts/5?arg_One=one&arg_One=two 

    WebSocket routes(网络套接字路由)

    • websocket 可以通过装饰路由实现

    demo:

    @app.websocket('/feed') async def feed(request, ws): while True: data = 'hello!' print('Sending: ' + data) await ws.send(data) data = await ws.recv() print('Received: ' + data) 另外,添加 websocket 路由方法可以代替装饰器 async def feed(request, ws): pass app.add_websocket_route(my_websocket_handler, '/feed') 

    响应( response )

    text

    from sanic import response @app.route('/text') def handle_request(request): return response.text('Hello world!') 

    HTML

    from sanic import response @app.route('/html') def handle_request(request): return response.hml('<p>Hello world!</p>') 

    JSON

    from sanic import response @app.route('/json') def handle_request(request): return response.json({'message': 'Hello world!'}) 

    File

    from sanic import response @app.route('/file') async def handle_request(request): return await response.file('/srv/www/whatever.png') 

    Streaming

    from sanic import response @app.route("/streaming") async def index(request): async def streaming_fn(response): response.write('foo') response.write('bar') return response.stream(streaming_fn, content_type='text/plain') 

    File Streaming

    • 对于大文件,文件和流的组合
    from sanic import response @app.route('/big_file.png') async def handle_request(request): return await response.file_stream('/srv/www/whatever.png') 

    Redirect

    from sanic import response @app.route('/redirect') def handle_request(request): return response.redirect('/json') 

    Raw

    • 没有进行编码的响应
    from sanic import response @app.route(‘/raw ’) def handle_request(request): return response.raw(‘ raw data ’) 

    Modify headers or status

    • 要修改头或状态代码,将标题或状态参数传递给这些函数
    from sanic import response @app.route(‘/json ’) def handle_request(request): return response.json( {‘ message ’: ‘ Hello world!’}, headers={‘ X-Served-By ’: ‘ sanic ’}, status=200 ) 

    更多的内容:Sanic 中文文档

    20 条回复    2017-11-01 13:52:04 +08:00
    markjack
        1
    markjack  
    OP
       2017-10-31 12:19:19 +08:00
    这是作者自己翻译的,在我的产品上发布,好像百度目前还搜不到 sanic 相关的中文文档,觉得非常不错,我就顺便帮忙推广下,大家多多支持,也多多支持我的产品
    PythonAnswer
        2
    PythonAnswer  
       2017-10-31 13:25:55 +08:00 via Android
    sanic 作者自己会中文吗,还不知道他是中国人
    markjack
        3
    markjack  
    OP
       2017-10-31 13:40:22 +08:00
    @PythonAnswer 哈哈哈 抱歉 我表达的问题,是有位用户翻译了关于 sanic 文档,因为目前 sanic 中文的教程比较少,觉得这个问答很有用,就帮他推广下
    takanasi
        4
    takanasi  
       2017-10-31 13:44:21 +08:00
    XIVN1987
        5
    XIVN1987  
       2017-10-31 13:46:10 +08:00
    感觉“ async def ”这种语法很丑啊,,为什么不直接“ async ”呢??就算用以前的 @asyncio.coroutine 修饰符也比“ async def ”好看
    markjack
        6
    markjack  
    OP
       2017-10-31 13:54:20 +08:00
    @takanasi 什么?
    takanasi
        7
    takanasi  
       2017-10-31 13:57:01 +08:00
    @markjack markdown 失败?

    ```
    from sanic.response import json
    @app.route(“/“)
    async def test(request):
    return json({ “ hello ”: “ world ” })
    ```
    Morriaty
        8
    Morriaty  
       2017-10-31 13:59:27 +08:00   1
    @XIVN1987 因为还有`async for`语句啊
    XIVN1987
        9
    XIVN1987  
       2017-10-31 14:02:19 +08:00
    @Morriaty
    原来如此,,多谢。。
    markjack
        10
    markjack  
    OP
       2017-10-31 14:02:27 +08:00
    @XIVN1987 因人而异吧,python3 用 async def 来定义协程函数,可能是觉得这种写法更像写函数,我觉得这样挺好,一眼就知道这个函数是一个协程函数
    markjack
        11
    markjack  
    OP
       2017-10-31 14:04:26 +08:00
    @takanasi

    这是作者编辑问题,正在跟他联系
    est
        12
    est  
       2017-10-31 14:07:06 +08:00
    拉到最后,终于看到链接了。
    akanasi
        13
    takanasi  
       2017-10-31 14:10:12 +08:00
    @XIVN1987 这个你都不知道?我告诉你其实还有 async with
    kongkongyzt
        14
    kongkongyzt  
       2017-10-31 14:26:31 +08:00 via Android
    想问下 sanic 有哪些异步 mysql driver 搭配一起使用
    XIVN1987
        15
    XIVN1987  
       2017-10-31 14:30:53 +08:00
    @takanasi
    确实是我孤陋寡闻了,,刚刚查了下 async def、async for、async with 是在 Python3.5 中一起新添加的特性
    hcnhcn012
        17
    hcnhcn012  
       2017-10-31 15:14:40 +08:00 via iPhone
    @XIVN1987 我也挺习惯用 @asyncio.coroutine 的,3.4 的语法改不过来了。。。
    n329291362
        18
    n329291362  
       2017-10-31 16:42:47 +08:00
    @kongkongyzt aiomysql
    4everLoveU
        19
    4everLoveU  
       2017-10-31 17:15:00 +08:00
    这语法,我咋感觉是在 flask 框架基础上自己封装出来的?
    也没有说高性能表现在哪里,和 flask、tornado 比有什么优势,解决了啥问题。
    可以讲讲这些
    julyclyde
        20
    julyclyde  
       2017-11-01 13:52:04 +08:00
    看这文档,觉得也就能类比 pocoo 那边的 Werkzeug toolkit
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5743 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 02:06 PVG 10:06 LAX 18:06 JFK 21:06
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86