成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

python 最快 web 框架 Sanci 快速入門

snifes / 1951人閱讀

摘要:詳細信息可以看下這個問題先在說下我的部署方式使用部署配置文件啟動方式總結(jié)試用了下,把之前的一個聊天機器人從改成了。預告下一篇將介紹如何使用一步一步創(chuàng)建一個聊天機器人。

簡介

Sanic 是一個和類Flask 的基于Python3.5+的web框架,它編寫的代碼速度特別快。
除了像Flask 以外,Sanic 還支持以異步請求的方式處理請求。這意味著你可以使用新的 async/await 語法,編寫非阻塞的快速的代碼。

關于 asyncio 包的介紹,請參考之前的一篇文章 python并發(fā)2:使用asyncio處理并發(fā)

Github 地址 是 https://github.com/channelcat/sanic,感興趣的可以去貢獻代碼。

既然它說速度特別快,我們先看下官方提供的 基準測試結(jié)果。

Sanic基準測試

這個測試的程序運行在 AWS 實例上,系統(tǒng)是Ubuntu,只使用了一個進程。

Sanic 的開發(fā)者說他們的靈感來自于這篇文章 uvloop: Blazing fast Python networking。

那我們就有必要看下uvloop是個什么庫。

uvloop

uvloop 是 asyncio 默認事件循環(huán)的替代品,實現(xiàn)的功能完整,切即插即用。uvloop是用CPython 寫的,建于libuv之上。
uvloop 可以使 asyncio 更快。事實上,它至少比 nodejs、gevent 和其他 Python 異步框架要快兩倍 。基于 uvloop 的 asyncio 的速度幾乎接近了 Go 程序的速度。

安裝 uvloop

uvloop 還只能在 *nix 平臺 和 Python3.5+以上版本使用。
使用pip安裝:

pip install uvloop

在 asyncio 代碼中使用uvloop 也很簡單:

import asyncio
import uvloop
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())

這得代碼使得對任何asyncio.get_event_loop() 的調(diào)用都將返回一個uvloop實例。

詳細的uvloop 介紹可以看下原文:uvloop: Blazing fast Python networking。

uvloop的github地址是https://github.com/MagicStack/uvloop。

現(xiàn)在我們開始學習Sanic:

安裝 Sanic
pip install sanic
創(chuàng)建第一個 sanic 代碼
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)

運行代碼: python main.py, 現(xiàn)在打開瀏覽器訪問 http://0.0.0.0:8000,你會看到 hello world!

如果你熟悉Flask,你會發(fā)現(xiàn),這個語法簡直和Flask一模一樣。

路由(Routing)

路由用于把一個函數(shù)綁定到一個 URL。下面是一些基本的例子:

@app.route("/")
def index():
    return text("Index Page")

@app.route("/hello")
def hello():
    return text("Hello World")

當然,你還可以動態(tài)的變化URL的某些部分,還可以為一個函數(shù)指定多個規(guī)則。

變量規(guī)則

通過把 URL 的一部分標記為 就可以在 URL 中添加變量。標記的 部分會作為關鍵字參數(shù)傳遞給函數(shù)。通過使用 ,可以 選擇性的加上一個轉(zhuǎn)換器,為變量指定特定的類型,如果傳入的類型錯誤,Sanic會拋出NotFound異常。請看下面的例子:

from sanic.response import text

@app.route("/tag/")
async def tag_handler(request, tag):
    return text("Tag - {}".format(tag))

@app.route("/number/")
async def integer_handler(request, integer_arg):
    return text("Integer - {}".format(integer_arg))

@app.route("/number/")
async def number_handler(request, number_arg):
    return text("Number - {}".format(number_arg))

@app.route("/person/")
async def person_handler(request, name):
    return text("Person - {}".format(name))

@app.route("/folder/")
async def folder_handler(request, folder_id):
    return text("Folder - {}".format(folder_id))
HTTP 請求類型

默認情況下,我們定義的URL只支持GET 請求,@app.route裝飾器提供了一個可選參數(shù)methods,這個參數(shù)允許傳入所有HTTP 方法。
例如:

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))

也可以簡寫為:

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 方法

除了@app.route裝飾器,Sanic 還提供了 add_route 方法。

@app.route 只是包裝了 add_route方法。

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/")
app.add_route(person_handler2, "/person/", methods=["GET"])
URL 構(gòu)建

如果可以匹配URL,那么Sanic可以生成URL嗎?當然可以,url_for() 函數(shù)就是用于構(gòu)建指定函數(shù)的URL的。它把函數(shù)名稱作為第一個參數(shù),其余參數(shù)對應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/")
async def post_handler(request, post_id):
    return text("Post - {}".format(post_id))

未定義變量會作為URL的查詢參數(shù):

url = app.url_for("post_handler", post_id=5, arg_one="one", arg_two="two")
# /posts/5?arg_one=one&arg_two=two

# 支持多值參數(shù)
url = app.url_for("post_handler", post_id=5, arg_one=["one", "two"])
# /posts/5?arg_one=one&arg_one=two
使用藍圖(Blueprint)

Sanic也提供了和Flask 類似的 Blueprint。
Blueprint有以下用途:

把一個應用分解為一套藍圖。這是針對大型應用的理想方案:一個項目可以實例化一個 應用,初始化多個擴展,并注冊許多藍圖。

在一個應用的 URL 前綴和(或)子域上注冊一個藍圖。 URL 前綴和(或)子域的參數(shù) 成為藍圖中所有視圖的通用視圖參數(shù)(缺省情況下)。

使用不同的 URL 規(guī)則在應用中多次注冊藍圖。

通過藍圖提供模板過濾器、靜態(tài)文件、模板和其他工具。藍圖不必執(zhí)行應用或視圖 函數(shù)。

blueprint 示例
from sanic import Sanic
from sanic.response import json
from sanic import Blueprint

bp = Blueprint("my_blueprint")

@bp.route("/")
async def bp_root(request):
    return json({"my": "blueprint"})
    
app = Sanic(__name__)
app.blueprint(bp)

app.run(host="0.0.0.0", port=8000, debug=True)

Sanic 使用 app.blueprint() 方法注冊blueprint。

使用藍圖注冊全局中間件
@bp.middleware
async def print_on_request(request):
    print("I am a spy")

@bp.middleware("request")
async def halt_request(request):
    return text("I halted the request")

@bp.middleware("response")
async def halt_response(request, response):
    return text("I halted the response")
使用藍圖處理異常
@bp.exception(NotFound)
def ignore_404s(request, exception):
    return text("Yep, I totally found the page: {}".format(request.url))
使用藍圖處理靜態(tài)文件

第一個參數(shù)指向當前的Python包
第二個參數(shù)是靜態(tài)文件的目錄

bp.static("/folder/to/serve", "/web/path")
使用url_for

如果要創(chuàng)建頁面鏈接,可以和通常一樣使用 url_for() 函數(shù),只是要把藍圖名稱作為端點的前綴,并且用一個點( . )來 分隔:

@blueprint_v1.route("/")
async def root(request):
    url = app.url_for("v1.post_handler", post_id=5) # --> "/v1/post/5"
    return redirect(url)


@blueprint_v1.route("/post/")
async def post_handler(request, post_id):
    return text("Post {} in Blueprint V1".format(post_id))
操作請求數(shù)據(jù)

對于web 應用來說對客戶端向服務器發(fā)送的數(shù)據(jù)做出相應很重要,在Sanic中由傳入的參數(shù) request來提供請求信息。

為什么不像Flask 一樣提供一個全局變量 request?

Flask 是同步請求,每次請求都有一個獨立的新線程來處理,這個線程中也只處理這一個請求。而Sanic是基于協(xié)程的處理方式,一個線程可以同時處理幾個、幾十個甚至幾百個請求,把request作為全局變量顯然會比較難以處理。

Request 對象常用參數(shù)有

json(any) json body
from sanic.response import json

@app.route("/json")
def post_json(request):
    return json({ "received": True, "message": request.json })
args(dict) URL請求參數(shù)

?key1=value1&key2=value2 將轉(zhuǎn)變?yōu)?/p>

{"key1": ["value1"], "key2": ["value2"]}
raw_args(dict) 和args 類似

?key1=value1&key2=value2 將轉(zhuǎn)變?yōu)?/p>

{"key1": "value1", "key2": "value2"}
form(dict)處理 POST 表單請求,數(shù)據(jù)是一個字典 body(bytes)處理POST 表單請求,數(shù)據(jù)是一個字符串

其他參數(shù)還有:

file

ip

app

url

scheme

path

query_string

詳細信息參考文檔: Request Data

關于響應

Sanic使用response 函數(shù)創(chuàng)建響應對象。

文本 response.text("hello world")

html response.html("

hello world

")

json response.json({"hello": "world"})

file response.file("/srv/www/hello.txt")

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")

redirect response.file("/json")

raw response.raw("raw data")

如果想修改響應的headers可以傳入headers 參數(shù)

from sanic import response

@app.route("/json")
def handle_request(request):
    return response.json(
        {"message": "Hello world!"},
        headers={"X-Served-By": "sanic"},
        status=200
    )
配置管理

應用總是需要一定的配置的。根據(jù)應用環(huán)境不同,會需要不同的配置。比如開關調(diào)試 模式、設置密鑰以及其他依賴于環(huán)境的東西。
Sanic 的設計思路是在應用開始時載入配置。你可以在代碼中直接硬編碼寫入配置,也可以使用配置文件。

不管你使用何種方式載入配置,都可以使用 Sanic 的 config 屬性來操作配置的值。 Sanic 本身就使用這個對象來保存 一些配置,擴展也可以使用這個對象保存配置。同時這也是你保存配置的地方。

配置入門

config 實質(zhì)上是一個字典的子類,可以像字典一樣操作:

app = Sanic("myapp")
app.config.DB_NAME = "appdb"
app.config.DB_USER = "appuser"

也可以一次更新多個配置:

db_settings = {
    "DB_HOST": "localhost",
    "DB_NAME": "appdb",
    "DB_USER": "appuser"
}
app.config.update(db_settings)
從對象導入配置
import myapp.default_settings

app = Sanic("myapp")
app.config.from_object(myapp.default_settings)

這里是我寫的聊天機器人的真實配置示例:https://github.com/gusibi/momo/

使用配置文件

如果把配置放在一個多帶帶的文件中會更有用。理想情況下配置文件應當放在應用包的 外面。這樣可以在修改配置文件時不影響應用的打包與分發(fā)
常見用法如下:

app = Sanic("myapp")
app.config.from_envvar("MYAPP_SETTINGS")

首先從 myapp.default_settings 模塊載入配置,然后根據(jù) MYAPP_SETTINGS 環(huán)境變量所指向的文件的內(nèi)容重載配置的值。在 啟動服務器前,在 Linux 或 OS X 操作系統(tǒng)中,這個環(huán)境變量可以在終端中使用 export 命令來設置:

$ export MYAPP_SETTINGS=/path/to/config_file
$ python myapp.py
部署

Sanic 項目還不是特別成熟,現(xiàn)在部署比較簡陋。對Gunicorn的支持也不完善。
詳細信息可以 看下這個問題 Projects built with sanic?

先在說下我的部署方式

使用 supervisord 部署

supervisord 配置文件: https://github.com/gusibi/momo/blob/master/supervisord.conf

啟動 方式

supervisord -c supervisor.conf
總結(jié)

試用了下Sanic,把之前的一個聊天機器人從Flask 改成了 Sanic。不得不說,如果你有Flask經(jīng)驗,大致看一下Sanic文檔就可以直接上手了。
并且Sanic 的速度比Flask 快很多,只是Sanic配套的包還是太少,用于生產(chǎn)環(huán)境有一定的風險。

最后對聊天微信聊天機器人感興趣的可以看下https://github.com/gusibi/momo。

預告

下一篇將介紹如何使用 Sanic 一步一步創(chuàng)建一個 聊天機器人。

參考鏈接

uvloop: Blazing fast Python networking

Sanic Githu 地址

Sanic 文檔


最后,感謝女朋友支持。

>歡迎關注 >請我喝芬達
彩蛋

魔魔是我們家巴哥的名字
貼一張魔魔的照片結(jié)束本篇文章。

文章版權歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/38644.html

相關文章

  • python并發(fā)3:使用asyncio編寫服務器

    摘要:上一篇我們介紹了包,以及如何使用異步編程管理網(wǎng)絡應用中的高并發(fā)。倒排索引保存在本地一個名為的文件中。運行示例如下這個模塊沒有使用并發(fā),主要作用是為使用包編寫的服務器提供支持。 asyncio 上一篇我們介紹了 asyncio 包,以及如何使用異步編程管理網(wǎng)絡應用中的高并發(fā)。在這一篇,我們主要介紹使用 asyncio 包編程的兩個例子。 async/await語法 我們先介紹下 asyn...

    rollback 評論0 收藏0
  • 后端API從入門到放棄指北

    摘要:菜鳥教程框架中文手冊入門目標使用搭建通過對數(shù)據(jù)增刪查改沒了純粹占行用的拜 后端API入門學習指北 了解一下一下概念. RESTful API標準] 所有的API都遵循[RESTful API標準]. 建議大家都簡單了解一下HTTP協(xié)議和RESTful API相關資料. 阮一峰:理解RESTful架構(gòu) 阮一峰:RESTful API 設計指南 RESTful API指南 依賴注入 D...

    Jeffrrey 評論0 收藏0
  • 后端API從入門到放棄指北

    摘要:菜鳥教程框架中文手冊入門目標使用搭建通過對數(shù)據(jù)增刪查改沒了純粹占行用的拜 后端API入門學習指北 了解一下一下概念. RESTful API標準] 所有的API都遵循[RESTful API標準]. 建議大家都簡單了解一下HTTP協(xié)議和RESTful API相關資料. 阮一峰:理解RESTful架構(gòu) 阮一峰:RESTful API 設計指南 RESTful API指南 依賴注入 D...

    sf190404 評論0 收藏0
  • 后端API從入門到放棄指北

    摘要:菜鳥教程框架中文手冊入門目標使用搭建通過對數(shù)據(jù)增刪查改沒了純粹占行用的拜 后端API入門學習指北 了解一下一下概念. RESTful API標準] 所有的API都遵循[RESTful API標準]. 建議大家都簡單了解一下HTTP協(xié)議和RESTful API相關資料. 阮一峰:理解RESTful架構(gòu) 阮一峰:RESTful API 設計指南 RESTful API指南 依賴注入 D...

    Airmusic 評論0 收藏0
  • 100 個基本 Python 面試問題第二部分(41-60)

    摘要:回到目錄評論區(qū)抽粉絲送書啦歡迎大家在評論區(qū)提出意見和建議抽兩位幸運兒送書,實物圖如下開發(fā)從入門到精通內(nèi)容簡介案例教學。 ? 作者主頁:海擁 ? 作者簡介:?CSDN...

    Tikitoo 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<