-
一個內建web應用的開發架構
kcw 快速建立cli和web架構
-
主要特性
- mysql對象化
- mongodb對象化
- 助手函數
- 配置支援
- 獨立路由配置 (預設 按檔案名/方法名)
- 資料庫助手
- 配置優先級
- 指令行快速建立web應用
- 指令行建立cli應用
- 分布式資料庫支援
- mysql事務支援
- 鍊試操作
- lock鎖
- web應用修改時時同步
- kcw指令行
kcw的環境要求如下:
python3或更高
安裝
pip install kcweb -i http://mirrors.aliyun.com/pypi/simple/
建立應用
create.py 檔案說明
建立一個app.py檔案,内容如下,執行python3 app.py建立應用 如下面的代碼建立了一個app應用,同時在app應用下建立了一個api子產品
from kcweb.create import create
create("app","api") # 建立項目
執行完上述檔案後,您的目錄結構應該是這樣,如下:
├─./ 架構目錄
├─app 公共方法目錄
│ ├─common 公共函數目錄
│ │ ├─__init__.py 函數檔案
│ ├─config 配置目錄
│ │ ├─__init__.py 配置檔案
│ ├─api 子產品目錄
│ │ ├─common 該子產品的公共函數目錄
│ │ │ ├─__init__.py 函數檔案
│ │ ├─controller 控制器目錄
│ │ │ ├─__init__.py 版本初始化檔案
│ │ │ ├─v1
│ │ │ │ ├─__init__.py 函數初始化檔案
│ │ │ │ ├─index.py 控制器檔案
│ │ │ ├─v2
│ │ │ │ ├─__init__.py 函數初始化檔案
│ │ │ │ ├─index.py 控制器檔案
│ │ ├─tpl 模闆檔案目錄
│ │ │ ├─v1
│ │ │ │ ├─index
│ │ │ │ │ ├─index.html 子產品檔案
│ │ │ ├─v1
│ │ │ │ ├─index
│ │ │ │ │ ├─index.html 子產品檔案
│ │ ├─__init__.py 控制器初始化檔案
│ ├─script 指令行腳本
│ │ ├─common 該子產品的公共函數目錄
│ │ │ ├─__init__.py 函數檔案
│ │ │ ├─win.py 類檔案
│ │ ├─test.py 腳本檔案
│ ├─static 靜态資源目錄
│ ├─runtime 緩存目錄
│ ├─__init__.py 自動導入子產品檔案
├─create.py
├─app.py 應用建立後生成的運作檔案(應用建立時自動建立)
執行完上述檔案在目前目錄下執行python3 app.py。 通過通路127.0.0.1:39001
-
配置
配置以變量定義、字典指派,所有的配置變量都是一個字典<li style="color:#000">核心配置:核心架構内置的配置檔案,無需更改</li><li style="color:#000">公共配置:每個應用的全局配置檔案</li><li style="color:#000">動态配置:主要是在視圖中進行(動态)更改配置,該配置方式隻在目前子產品和當次請求有效,因為不會儲存到配置檔案中</li><li style="color:#000">方法配置:主要是通過特定的方法傳入配置資訊</li> </ul>
注意:redis連接配接池連結模式下不支援動态配置,動态配置不生效,如果您的項目需要redis動态配置,那麼您需要在子產品配置中設定redis連接配接方式為False。如:redis['pattern']=False
配置優先級:
核心配置 < 公共配置 < 動态配置 < 方法配置
自定義配置:
自定義配置就是需要在應用下使用自己的配置,如:調用某平台的接口需要使用的appid和appkey需要單獨配置時所使用的配置
配置檔案:
完整配置如下:
# 應用配置
app['app_debug']=True #是否開啟調試模式
app['tpl_folder']='./tpl' #設定模闆檔案目錄名 注意:不能配置目錄路徑
app['before_request']='before_request' #設定請求前執行的函數
app['after_request']='after_request' #設定請求後執行的函數
app['staticpath']='app/static'
# redis配置
redis['host']='127.0.0.1' #伺服器位址
redis['port']=6379 #端口
redis['password']='' #密碼
redis['db']=0 #Redis資料庫 注:Redis用0或1或2等表示
redis['pattern']=True # True連接配接池連結 False非連接配接池連結
redis['ex']=0 #過期時間 (秒)
#緩存配置
cache['type']='File' #驅動方式 支援 File Redis
cache['path']='runtime/cachepath' #緩存儲存目錄
cache['expire']=120 #緩存有效期 0表示永久緩存
cache['host']=redis['host'] #Redis伺服器位址
cache['port']=redis['port'] #Redis 端口
cache['password']=redis['password'] #Redis登入密碼
cache['db']=1 #Redis資料庫 注:Redis用1或2或3等表示
# session配置
session['type']='File' #session 存儲類型 支援 file、Redis
session['path']='runtime/session' #session緩存目錄
session['expire']=86400 #session預設有效期 該時間是指session在服務的保留時間,通常情況下浏覽器上會保留該值的10倍
session['prefix']="KCW" # SESSION 字首
session['host']=redis['host'] #Redis伺服器位址
session['port']=redis['port'] #Redis 端口
session['password']=redis['password'] #Redis登入密碼
session['db']=2 #Redis資料庫 注:Redis用1或2或3等表示
# 預設資料庫配置
database['type']='mysql' # 資料庫類型 目前支援mysql和sqlite
database['host']=['127.0.0.1']#伺服器位址 [位址1,位址2,位址3...] 多個位址分布式(主從伺服器)下有效
database['port']=[3306] #端口 [端口1,端口2,端口3...]
database['user']=['root'] #使用者名 [使用者名1,使用者名2,使用者名3...]
database['password']=['root'] #密碼 [密碼1,密碼2,密碼3...]
database['db']=['test'] #資料庫名 [資料庫名1,資料庫名2,資料庫名3...]
database['charset']='utf8' #資料庫編碼預設采用utf8
database['pattern']=False # True資料庫長連接配接模式 False資料庫短連接配接模式 注:建議web應用使用短連接配接,cli應用使用長連接配接
database['cli']=False # 是否以cli方式運作
database['dbObjcount']=1 # 連接配接池數量(單個資料庫位址連結數量),資料庫連結執行個體數量 mysql長連結模式下有效
database['deploy']=0 # 資料庫部署方式:0 集中式(單一伺服器),1 分布式(主從伺服器) mysql資料庫有效
database['master_num']=1 #主伺服器數量 不能超過host伺服器數量 (等于伺服器數量表示讀寫不分離:主主複制。 小于伺服器表示讀寫分離:主從複制。) mysql資料庫有效
database['master_dql']=False #主伺服器是否可以執行dql語句 是否可以執行select語句 主伺服器數量大于等于host伺服器數量時必須設定True
database['break']=0 #斷線重連次數,0表示不重連。 注:cli模式下 10秒進行一次重連并且連接配接次數是目前配置的300倍
#sqlite配置
sqlite['db']='kcwdb' # 資料庫檔案存放位址
#mongodb配置
mongo['host']='127.0.0.1'
mongo['port']='27017'
mongo['user']=''
mongo['password']=''
mongo['db']='test'
#路由配置
route['default']=True #是否開啟預設路由 預設路由開啟後面不影響以下配置的路由,子產品名/版本名/控制器檔案名/方法名 作為路由位址 如:http://www.kcw.com/api/v1/index/index/
route['modular']=[{"www":"api"},{"127":"api"},{"192":"api"}] #配置域名子產品 配置後位址為:http://www.kcw.com/v1/index/index/ 注意:如果使用的是代理伺服器需要把代理名稱設定為目前配置的域名,否則不生效
route['edition']='' #預設路由版本,配置後位址為 http://www.kcw.com/index/index/
route['files']='index' #預設路由檔案
route['funct']='index' #預設路由函數
route['methods']=['POST','GET'] #預設請求方式
#email配置
email['sender']='' #發件人郵箱賬号
email['pwd']='' #發件人郵箱密碼(如申請的smtp給的密碼)
email['sendNick']='' #發件人昵稱
email['sendNick']='' #發件人昵稱
email['theme']='' #預設主題
email['recNick']='' #預設收件人昵稱
#其他配置 如:
other['aliyun']['AccessKey_ID']='' #配置阿裡雲賬戶id
other['aliyun']['AccessKey_Key']='' #配置阿裡雲賬戶key
方法配置:
下面是使用mysql的方法配置資料庫資訊
mysql('test').connect({"host":"127.0.0.1"}).find()
動态配置:
動态修改配置資訊,如動态修改資料庫連結ip、端口和重連次數
config.database['host']=['127.0.0.1'] #伺服器位址
config.database['port']=[3306] #端口
config.database['break']=1 #斷線重連次數
動态配置不建議在web應用中使用,因為他是全局的,通常情況下,如果您的web應用需要部分接口需要修改配置資訊應該使用方法配置,cli腳本可以使用動态配置
使用配置:
擷取配置資訊
print(config.app) #擷取app配置資訊
print(config.database['host']) #擷取資料庫配置資訊
print(config.other['aliyun']) #擷取aliyun配置資訊
...
運作檔案
app.py是web應用的運作檔案,你您隻需要用python執行app.py即可運作web應用,app.py檔案是您建立應用時生成的
app.py内容如下:
# #gunicorn -b 0.0.0.0:39010 app:app
from kcweb import web
import app as application
app=web(__name__,application)
if __name__ == "__main__":
#app 是目前檔案名 host監聽ip port端口
app.run("app",host="0.0.0.0",port="39001")
您可以根據上面的備注修改相關的資訊
URL設計
kcweb在沒有定義路由的情況下典型的URL通路規則是:
http://serverName/子產品/版本/控制器/函數/[參數名/參數值...]
kcweb在建立應用時預設配置了基本路由
route['default']=True #是否開啟預設路由 預設路由開啟後面不影響以下配置的路由,子產品名/版本名/控制器檔案名/方法名 作為路由位址 如:http://www.kcw.com/api/v1/index/index/
route['modular']=[{"www":"api"},{"127":"api"},{"192":"api"}] #配置域名子產品 配置後位址為:http://www.kcw.com/v1/index/index/ 注意:如果使用的是代理伺服器需要把代理名稱設定為目前配置的域名,否則不生效
route['edition']='v1' #預設路由版本,配置後位址為 http://www.kcw.com/index/index/
route['files']='index' #預設路由檔案
route['funct']='index' #預設路由函數
route['methods']=['POST','GET'] #預設請求方式
是以您的URL通路規則是:
http://serverName/控制器/函數/[參數名/參數值...]
方法
公共方法:
如果您定義的方法需要被目前應用的所有子產品子產品使用,那麼你應該把您的的方法定義在公共方法檔案中,所有方法名應該以下劃線方式命名,并且不能出現架構提供的方法名,下面定義的方法可以在其他子產品下使用
├─./
├─app 應用目錄
│ ├─common 公共方法目錄
│ │ ├─__init__.py 公共方法檔案
from kcweb.common import *
from app import config
def returnjson(data=[],code=0,msg="成功",status='200 ok'):
"""在浏覽器輸出包裝過的json
參數 data 結果 預設[]
參數 code body狀态碼 預設0
參數 msg body狀态描述 預設 成功
參數 status http狀态碼 預設 200
傳回 json字元串結果集
"""
res={
"code":code,
"msg":msg,
"time":times(),
"data":data
}
return json_encode(res),status,{"Content-Type":"application/json; charset=utf-8"}
子產品方法:
如果您定義的方法隻是為某個子產品使用,那麼你應該把您的的方法定義在子產品方法檔案中,所有方法名應該以下劃線方式命名,并且不能出現架構提供的方法名和公共方法裡定義的方法名,下面定義的方法可以在目前子產品下使用
├─./
├─app 應用目錄
│ ├─api 子產品目錄(簡稱子產品)
│ │ ├─common 目前子產品方法目錄
│ │ │ ├─__init__.py 目前子產品方法檔案
from app1.common import *
#下面的方法在目前子產品中有效
G=globals.G
#下面的方法在目前子產品中有效
def before_request():
G.userinfo=get_session("userinfo")
print('api子產品在請求前執行,我是要在配置檔案配置後才能生效哦!',G.userinfo)
def after_request():
print('api子產品在請求後執行,我是要在配置檔案配置後才能生效哦!')
def set_session(name,value,expire=None):
"設定session"
return session.set("app1api"+str(name),value,expire)
def get_session(name):
"擷取session"
return session.get("app1api"+str(name))
def del_session(name):
"删除session"
return session.rm("app1api"+str(name))
def tpl(path,**context):
return Template("/api/tpl"+str(path),**context)
控制器定義
控制器檔案通常放在[應用]/[子產品]/controller/[版本]目錄下面,檔案名統一保持小寫。一個視圖檔案格式應該是如下:returnjson方法的作用是在浏覽器輸出包裝過的json,當然你也可以修改該方法的值
from [應用].[子產品].common import *
def index1():
return returnjson("index")
def index2():
return returnjson("index")
...
通路的url是(在沒有定義路由的情況下)
http://server/[子產品]/[版本]index/index1 http://server/[子產品]/[版本]index/index2 ##視圖初始檔案 ______init__.py
from . import index
# def error(err,data):
# "該函數在目前目錄下無法比對時被調用"
# return data,"200",{"Content-Type":"text/json; charset=utf-8"}
建立控制器檔案後,您需要在目前版本目錄下的______init__.py檔案中導入控制器檔案,____init.py檔案也可以定義函數,但他不能調用common下的方法
更多文檔參考 :http://intapp.kwebapp.cn/index/index/doc/docde/1