2020-06-25
Flask-AppBuilder .. MVC … 還不錯以後來用
與安裝 Flask 一樣參考
https://echochio-tw.github.io/2019/09/flask+uwsgi/
在 source env/bin/activate 後安裝相關套件
python -m pip install flask-appbuilder
或是 … 有 requirements.txt …
run.py 我改成這樣看一下是不是與 wsgi.py 很像
from app import app
app.run(host="0.0.0.0")
wsgi.py 這樣設會直接帶起flask-AppBuilder沒問題
from app import app as application
if __name__ == "__main__":
application.run()
這邊就不紀錄 flask + uwsgi 的方式了
紀錄一下 root 測試環境
建立工作目錄
flask fab create-app
改資料庫為 mysql 編輯 config.py
SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:password@localhost/message'
其中
帳號 : root
密碼 : password
主機 : locqlhost
資料庫 : message
建立 admin 帳密
flask fab create-admin
執行
python3 run.py
這就不截圖了
改名 … config.py 的
APP_NAME = "短信APP"
修改首页 /app/index.py
from flask_appbuilder import IndexView
class MyIndexView(IndexView):
index_template = 'new_index.html'
templates中new_index.html 改所想要的首页
修改app/iniy.py 在AppBuilder初始化的时候,指定indexview的值
from app.index import MyIndexView
appbuilder = AppBuilder(app, db.session, indexview=MyIndexView)
加 Helloword … app/views.py 不寫了 … google 都有
好了這邊紀錄一下 API 部分 app/views.py (這個與 flask 相近只比他寫在一個 class 就可)
要 import 那些就沒詳查了 ….
from flask import render_template
from flask_appbuilder.models.sqla.interface import SQLAInterface
from flask_appbuilder import ModelView, ModelRestApi
from . import appbuilder, db
from flask_appbuilder import ModelView,AppBuilder,expose,BaseView,has_access
from .models import Member,Message_list
from flask_appbuilder.api import BaseApi, expose
from flask import jsonify
from flask import request
def telegram_send(bot_message,bot_chatID = '-341334440',bot_token = '917680011:AAFpNGEoiebe1yXbkHDVbS11uKA12DSJLjs'):
send_text = 'https://api.telegram.org/bot' + bot_token + '/sendMessage?chat_id=' + bot_chatID + '&parse_mode=Markdown&text=' + bot_message
response = requests.get(send_text)
return response.json()
class ApiView(BaseView):
route_base = "/api"
@expose("/telegram/<message>", methods=['GET'])
def telegramdo(self,message):
j = telegram_send(message) # 這邊呼叫 def 要放 class 外面,.. 這邊是 telegram 簡易跳轉程式
return j
@expose("/list", methods=['GET'])
def list(self):
return jsonify({'res':'OK','apis':['/apiv1/devices','/apiv1/accesses','/apiv1/accounts']})
@expose("/do/<p>", methods=['GET'])
def alist(self,p):
return jsonify({p:'OK'})
@expose('/method', methods=['GET'])
def method(self):
dic = request.args
return jsonify(dic)
@expose('/dns/<function>', methods = ['POST'])
def dns(self,function):
if (request.is_json):
content = request.get_json()
else:
content = ''
print (function)
return content
@expose("/id/<p>/<s>", methods=['GET'])
def alist(self,p,s):
a = db.session.query(Member).filter_by(user = p,signature = s).first()
if(a is None):
d = []
else:
d = [{'user':a.user,'nickname':a.nickname,'user_password':a.user_password,'signature':a.signature,'point':a.point,'account':a.account,'password':a.password,'extno':a.extno}]
return jsonify(d)
@expose('/get', methods=['GET'])
def method(self):
dic = request.args
if ('user' not in dic) and ('signature' not in dic):
d =[]
else:
p = dic['user']
s = dic['signature']
a = db.session.query(Member).filter_by(user = p,signature = s).first()
if(a is None):
d = []
else:
d = [{'user':a.user,'nickname':a.nickname,'user_password':a.user_password,'signature':a.signature,'point':a.point,'account':a.account,'password':a.password,'extno':a.extno}]
return jsonify(d)
@expose("/wri/<u>/<s>/<p>", methods=['GET'])
def alist(self,u,s,p):
a = db.session.query(Member).filter_by(user = u,signature = s).first()
if(a is None):
d = []
else:
# update point new value
a.point = p
db.session.commit()
d = [{'user':a.user,'nickname':a.nickname,'user_password':a.user_password,'signature':a.signature,'point':a.point,'account':a.account,'password':a.password,'extno':a.extno}]
dt=datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
#wirte to other table (add new one)
todo = Message_list(message='test '+user,send_request = dt, returnlog = 'test '+signature, point = 10)
db.session.add(todo)
db.session.commit()
return jsonify(d)
appbuilder.add_api(ApiView)
呼叫方式
http://{domain}/api/{resource}/{params}
測試結果看一下
curl 'http://192.168.8.121:5000/api/list'
輸出 : {"apis":["/apiv1/devices","/apiv1/accesses","/apiv1/accounts"],"res":"OK"}
curl 'http://192.168.8.121:5000/api/do/hello'
輸出 : {"hello":"OK"}
curl 'http://192.168.8.121:5000/api/method?data=user'
輸出 : {"data":"user"}
curl 'http://192.168.8.121:5000/api/dns/set' -X POST -H "Content-Type:application/json" -d '{"domain" : "test.com"}'
輸出 : {"domain":"test.com"}
資料庫的部分 拿我亂寫的
app/models.py
from flask_appbuilder import Model
from sqlalchemy.dialects.mysql import LONGTEXT
from sqlalchemy.orm import relationship
from sqlalchemy import Column, Integer, String, DateTime, Text
class Member(Model):
id = Column(Integer, primary_key=True)
user = Column(String(30), unique = True, nullable=False)
nickname = Column(String(50))
user_password = Column(String(30))
signature = Column(String(50))
point = Column(Integer)
account = Column(String(50))
password = Column(String(50))
extno = Column(String(50))
def __repr__(self):
return self.name
class Message_list(Model):
id = Column(Integer, primary_key=True)
message = Column(Text)
send_request = Column(DateTime)
returnlog = Column(LONGTEXT)
point = Column(Integer)
def __repr__(self):
return self.message
app/views.py
from flask import render_template
from flask_appbuilder.models.sqla.interface import SQLAInterface
from flask_appbuilder import ModelView, ModelRestApi
from . import appbuilder, db
from flask_appbuilder import ModelView,AppBuilder,expose,BaseView,has_access
from .models import Member,Message_list
from flask_appbuilder.api import BaseApi, expose
from flask import jsonify
class MemberModelView(ModelView):
datamodel = SQLAInterface(Member)
#修改列名称
label_columns = {'user':'帳號','nickname':'帳戶名稱','password':'密碼','signature':'客戶金鑰','point':'點數','account':'供應商帳號'}
#定义列显示名称
list_columns = ['user','nickname','password','signature','point','account'] #定义视图中要显示的字段
show_fieldsets = [
(
'Summary',
{'fields':['user','nickname','password','signature','point','account']}
),
]
class MessagelistModelView(ModelView):
datamodel = SQLAInterface(Message_list)
#只能列表
base_permissions = ['can_list','can_show']
#一頁五筆
page_size=5
#修改列名称
label_columns = {'message':'傳送資訊','send_request':'傳送時間','returnlog':'回應資訊','point':'剩餘點數'}
#定义列显示名称
list_columns = ['send_request','message','returnlog','point'] #定义视图中要显示的字段
show_fieldsets = [
(
'Summary',
{'fields':['send_request','message','returnlog','point']}
),
]
# 首先使用db.create_all()根据数据库模型创建表,然后再将视图添加到菜单。
db.create_all()
appbuilder.add_view(MemberModelView,'會員列表',icon = 'fa-address-card-o',category = '會員資訊')
appbuilder.add_view(MessagelistModelView,'紀錄列表',icon = 'fa-address-card-o',category = '紀錄')
這個還沒試應該是OK的
#todo = Todo(content='hacking')
#db.session.add(todo)
#db.session.commit()
#todo = Todo.query.filter_by(contant='hacking').update({'content': 'reading'})
#db.session.commit()
# todo = Todo.query.filter_by(content='reading').first()
# db.session.delete(todo)
#db.session.commit()
詳細在這裡 : 全會還真難
https://flask-appbuilder.readthedocs.io/en/latest/
GCP 用 App Engine
gcloud auth list
gcloud config list project
gcloud app create --project=$DEVSHELL_PROJECT_ID
git clone https://github.com/GoogleCloudPlatform/python-docs-samples
cd python-docs-samples/appengine/standard_python3/hello_world
sudo apt-get update
sudo apt-get install virtualenv
virtualenv -p python3 venv
pip install -r requirements.txt
pip install flask-appbuilder
flask fab create-app
flask fab create-admin
cd 到所建的目錄 建立 main.py
from app import app as application
if __name__ == "__main__":
application.run()
要有三個檔案
app.yaml main.py requirements.txt
建立與確認
cp ../app.yaml app.yaml
pip freeze > requirements.txt
ls -l
dev 測試
python3 main.py
push 上去
gcloud app deploy
gcloud app browse