本文基于sanic 官方文檔解釋及自己閱讀后的感想.
首先什么是sanic?
sanic是一款用python3.5+寫的web framework。它有一下幾個(gè)特點(diǎn):
1.flask-like的語法風(fēng)格,簡(jiǎn)單易學(xué)
2.輕量
3.基于python3.5 async/await 及uvloop 它的性能非常好
4.支持websocket
…………
特性先不BB了。
讓我們切入正題, 首先建立一個(gè)簡(jiǎn)單的http應(yīng)用
from sanic import Sanic
from sanic.response import text
app = Sanic()
@app.route("/")
async def test(request):
return text("hello world")
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000)
是不是很簡(jiǎn)單!
首先我們導(dǎo)入sanic庫的Sanic類以及sanic.response類中的text方法
接著通過@app.route裝飾器編寫我們的url地址
然后我們寫了一個(gè)test的api,這個(gè)方法定義了當(dāng)有人訪問時(shí)返回一個(gè)hello world的字符串
注意async關(guān)鍵字
玩py3.5的小伙伴肯定很熟悉了吧?沒錯(cuò)這個(gè)接口是異步調(diào)用。
至于異步調(diào)用的好處 我這里也就不再累述了。
接著我們打開瀏覽器,輸入我們的主機(jī)ip+8000 我們就能看到hello world了
當(dāng)然我們也可以在url中帶入我們需要的參數(shù),例如:
from sanic.response import text
@app.route('/tag/<tag>')
async def tag_handler(request, tag):
return text('Tag - %s'%tag)
我們?cè)谠紆rl后面添加<>標(biāo)記代表需要額外再url中傳遞的參數(shù)。這時(shí)當(dāng)我們?cè)L問ip/tag/1 的時(shí)候,瀏覽器會(huì)顯示出 Tag -1 的字樣。
如果剛才的實(shí)例我只想讓int類型的數(shù)據(jù)傳遞進(jìn)來,有什么方便的方法嗎? 答案是肯定的,我們把才的代碼稍加修改一下,變成下面這樣:
@app.route('/tag/<tag:int>')
async def tag_handler(request, tag):
return text('Tag - %s'%tag)
沒錯(cuò) 我只是加了個(gè):int 就完成了這個(gè)功能。并且當(dāng)傳參不是int類型時(shí)頁面將自動(dòng)跳轉(zhuǎn)到404頁面。是不是很棒呢!這樣再也不需要在方法中去判斷限制了。
當(dāng)然了我們還可以做其他的限制,比如用正則表達(dá)式限制該傳參必須是字母。
@app.route('/tag/<tag:[A-z]+>')
async def tag_handler(request, tag):
return text('Tag - %s'%tag)
到現(xiàn)在為止我們都是基于get的操作請(qǐng)求,那我要用POST提交數(shù)據(jù)呢?這個(gè)也很簡(jiǎn)單。只要在@app.route 裝飾器中添加 methods=['POST']就可以了。
如以下代碼:
@app.route('/tag/<tag:int>', methods=['POST'])
async def tag_handler(request, tag):
return text('Tag - %s'%tag)
有時(shí)候不想在每個(gè)方法上都寫一個(gè)url裝飾器,那怎么辦?那我們可以這樣寫:
async def tag_handler(request, tag):
return text('Tag - %s'%tag)
app.add_route(tag_handler, '/tag')
ok接下來介紹一個(gè)很有趣的東西. url_for
它能根據(jù)api的處理方法生成url。
@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))
當(dāng)我訪問/ 首頁時(shí) 會(huì)自動(dòng)跳轉(zhuǎn)到/post 還會(huì)自動(dòng)在url中攜帶post_id=5的參數(shù)
最后我訪問/ 首頁時(shí) 獲得是 Post - 5 的數(shù)據(jù)信息。
當(dāng)然它擁有很多的傳參類型 下面的代碼展示的就是不同類型下傳參的格式變化
url = app.url_for('post_handler', post_id=5, arg_one='one', _anchor='anchor')
# /posts/5?arg_one=one#anchor
url = app.url_for('post_handler', post_id=5, arg_one='one', _external=True)
# //server/posts/5?arg_one=one
# _external requires passed argument _server or SERVER_NAME in app.config or url will be same as no _external
url = app.url_for('post_handler', post_id=5, arg_one='one', _scheme='http', _external=True)
# http://server/posts/5?arg_one=one
# when specifying _scheme, _external must be True
# you can pass all special arguments one time
url = app.url_for('post_handler', post_id=5, arg_one=['one', 'two'], arg_two=2, _anchor='anchor', _scheme='http', _external=True, _server='another_server:8888')
# http://another_server:8888/posts/5?arg_one=one&arg_one=two&arg_two=2#anchor
最后介紹下websocket的路由方法
@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)
是不是也很簡(jiǎn)單呢?
同樣我們也可以用app.add_websocket_route(feed, '/feed')
來使用不基于裝飾器的url規(guī)則編寫。
下一節(jié),我將分享sanic如何接收數(shù)據(jù)處理后并返回?cái)?shù)據(jù)。