我們知道python的異步web框架sanic 的高性能,併發特性甚至接近golang, 底層使用uvloop。https://github.com/huge-success/sanic
雖然sanic寫簡單的web應用特別容易,但python3 異步語法和 async 需要配套相關的數據庫異步庫使用起來不方便,同時滿足使用django等的習慣,由於目前沒看見sanic有orm相關處理,以及restful 也不符合使用習慣。因此決定自定義一個:https://github.com/laoyin/easy_sanic
a、支持簡單orm
b、異步pg數據庫支持
c、支持restful
d、支持redis等操作
TODO:目前easy_sanic 已經支持上述,接下來將進行swagger支持。
如何安裝:
pip install easy_sanic
如何使用:
在github上已經進行了easy sanic使用說明,再次進行描述,希望對sanic感興趣的人有幫助。
easy sanic 框架,集成了sanic,同時自定義async orm, (目前支持postgres) easyrestful。簡單好用,你可以完全不用掌握python3 aysncio相關知識 也能寫出高性能服務。
easy sanic 目標是 快速打造微服務。
easy sanic framework.
創建項目入口:app.py
import asyncio
import opentracing
from sanic import Sanic
from aioredis import create_redis_pool
from easy_sanic.utils.ascci_helper import init_text
from easy_sanic.utils.aio_redis import SanicRedis
from easy_sanic.db.db import ConnectionPool
from url import app_url # 此處url 爲之定義url文件,需要自己添加,文檔有介紹如何引用
app = Sanic(__name__)
app.config.update({
'DB_CONFIG':{
'user':'postgres',
'password':'password',
'database':'',
'host':'',
'port':''
}
})
redis_conf = {
'REDIS':{
'address': ("REDIS_HOST", "REDIS_PORT"),
'db': 1,
}
}
redis_conf['REDIS']['password'] = "REDIS_PASSWORD"
app.config.update(redis_conf)
@app.listener('before_server_start')
async def before_server_start(app, loop):
app_url(app)# 引用url
queue = asyncio.Queue()
app.queue = queue
app.db = await ConnectionPool(loop=loop).init(app.config['DB_CONFIG'])
_c = dict(loop=loop)
config = app.config.get('REDIS')
for key in ['address', 'db', 'password', 'ssl', 'encoding', 'minsize',
'maxsize', 'create_connection_timeout']:
if key in config:
_c.update({key: config.get(key)})
_redis = await create_redis_pool(**_c)
app.redis = _redis
app.conn = _redis
@app.listener('before_server_stop')
async def before_server_stop(app, loop):
app.redis.close()
await app.redis.wait_closed()
await app.service.deregister()
app.queue.join()
if __name__ == '__main__':
print(init_text)
app.run(host='0.0.0.0', port=7001)
如何定義url:
url:
from yourview.py import YourClass
def app_url(app):
app.router.add(uri='/hello', methods=['GET'], handler=YourClass().as_views)
#yourviews.py
from sanic.response import json
from easy_sanic.restful.operation_handler import ResourceBase, operation
class RestStatus:
@classmethod
def response_status(cls, ret, message, data=""):
return json({"ret": ret, "message": message, "data":data})
class YourClass(ResourceBase):
async def get(self, request):
return RestStatus.response_status(200, "ok", data=data)
async def post(self, request):
request_data = request.form
return RestStatus.response_status(200, "ok", data=data)
def delete(self, request):
print("i am delete")
return RestStatus.response_status(400, "request method error")
@operation(flag=True)
def custom_url(self, request):
print("i am print hh")
return RestStatus.response_status(400, "request method error")
@operation(flag=False)
def hello(self, request):
print("afwefaewfaw")
return RestStatus.response_status(200, "pengfeng")
現在你可以通過url 進行 get、post、delete 訪問了,支持http(get、post、delete、put) 同時可以自定義方法
使用operation, flag=True 爲get方法, False 爲 post方法,使用如下:
http://127.0.0.1:port/hello?operation=custom_url
如何定義orm models: orm: models.py
from easy_sanic.db.orm import SqlObject, FieldObject, TableName
#User message
class User(metaclass=SqlObject):
id = FieldObject('id', 'varchar(200) primary key')
name = FieldObject('name', 'varchar(200)')
password = FieldObject('password', 'varchar(200)')
table_name = TableName('users')
如何使用model orm
在view 裏面
from easy_sanic.restful.operation_headler import ResourceBase, operation
class ProvilegeRole(ResourceBase):
async def get(self, request):
data = await User.filter(request, id='yinxingpan')
new_obj = User(id="yinxingpan", name="haha2", password="123")
result = await new_obj.save(request)
print(data)
return RestStatus.response_status(200, "ok", data=data)
其中 model.filter、model.save 必須傳遞request方法
目前支持postgres,redis
redis的使用:
with await request.app.conn as conn:
# await conn.get("NOT_RESTRICT_URL") restrict
url_status = await conn.execute('SISMEMBER', "key", "value")
部署: gunicorn app:app --bind 0.0.0.0:7001 --worker-class sanic.worker.GunicornWorker -w 2