Flask速成項目:Flask實現計算機資源的實時監控

不少人都說使用Python開發WEB應用很是方便,那麼對於WEB新手來講,到底有多方便呢?本文即將展現給你Python的魔法。 本文將經過一個實例:Flask實現計算機資源的實時監控,迅速帶你入門Flask開發。 先說一下個人水平,博主的專業並非作WEB開發的,對於WEB方面,只會寫爬蟲,所以,只能看懂html,略看得懂css與js,我估計有不少像我同樣的小夥伴,所以,若是你的WEB掌握的水平在我之上或與我至關,那麼,這篇文章將是你迅速入門Flask的終極教程javascript

先放上一張成果圖: 結果 訪問,瀏覽器可以實時顯示個人電腦的兩個CPU的使用狀況,這裏特意採用兩種顯示方式,方便你們學習代碼。php

flask介紹

Flask is a microframework for Python based on Werkzeug, Jinja 2 and good intentions. And before you ask: It’s BSD licensed! 搞科研或者搞技術,仍是直接看英文吧,英文是你走向NB的基礎。css

flask安裝

能夠參考我以前的文章:html

  1. Python配置虛擬環境
  2. ubuntu18.04 安裝flask
  3. Flask項目結構

另外,須要安裝psutilflask_socketio包,可直接使用pip安裝前端

構建flask項目結構

在你的目錄下新建以下的目錄與文件:java

boss@boss-N501JW:~/Desktop/projects/CPU_memory$ tree
.
|-- app.py
`-- templates
`-- index.html

1 directory, 2 files

很是形象的解釋下flask完成的任務 瀏覽器向服務器發送請求,服務器將html源代碼發送給瀏覽器,瀏覽器將html解析成可視化的東西展現給用戶。也就是說,用戶接收到的老是一個html文件,那flask在整個過程當中完成了什麼任務呢? 請把Flask想象成一個火腿腸加工廠,將輸送給火腿腸加工廠火腿腸加工廠生產出火腿腸。一樣,將用戶請求,例如訪問https://xujh.top這一請求發送給flaskflask可以生產出html。 將請求發送給flask是經過flask中的路由來實現的,flask是經過直接返回或返回模板來生成html的。python

對於上述項目結構的構成,app.py中實現了路由及啓動功能,templates文件夾中是模板文件,(這裏插一句:我曾經看到不少人,在讀某個用flask作的WEB項目的源碼,一打開templates文件夾中,發現了不少css,js,html文件,一打開這些文件,發現幾百上前行,一會兒頭都大了,立馬放棄了讀代碼,哈哈哈哈),其實,對於像我同樣專業不是作前端的小夥伴,徹底能夠不用擔憂,這些文件其實能夠一行都不寫,例如能夠用Bootstrap框架來作前端,使用Bootstrap要寫代碼?兄弟,你不會用可視化編輯工具嘛!!! 等之後咱們作大項目,咱們主要寫的也就是除了templates文件夾中之外的文件。前端不會別擔憂,我也不會。jquery

對於這篇文章所要實現的目標,咱們作一個小結:ajax

  1. 執行app.py,計算機啓動flask自帶的服務器,開始容許WEB訪問
  2. 用戶使用瀏覽器訪問網址
  3. flask接受到用戶的請求後,app.py進行邏輯上的處理,將index.html傳送給瀏覽器。

源碼分析

app.py

源代碼的分析在註釋中,你們必定能看懂!json

# -*- coding:utf-8 -*-
'''
CPU_and_MEM_Monitor
思路:後端後臺線程一旦產生數據,即刻推送至前端。
好處:不須要前端ajax定時查詢,節省服務器資源。
'''

import psutil #這個庫能夠用來獲取系統的資源數據,詳細能夠看文檔
import time

from threading import Lock

from flask import Flask, render_template, session, request
from flask_socketio import SocketIO, emit

# Set this variable to "threading", "eventlet" or "gevent" to test the
# different async modes, or leave it set to None for the application to choose
# the best option based on installed packages.
async_mode = None

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app, async_mode=async_mode)


thread = None
thread_lock = Lock()



# 後臺線程 產生數據,即刻推送至前端
def background_thread():
count = 0
while True:
socketio.sleep(2)
count += 1
t = time.strftime('%M:%S', time.localtime()) # 獲取系統時間(只取分:秒)
cpus = psutil.cpu_percent(interval=None, percpu=True) # 獲取系統cpu使用率 non-blocking
socketio.emit('server_response',
{'data': [t] + list(cpus)[0:4], 'count': count},
namespace='/test') # 注意:這裏不須要客戶端鏈接的上下文,默認 broadcast = True !!!!!!!
print [t] +list(cpus)[0:4]
print 100*'*'

# 當用戶訪問'/'時,執行index()函數。這也是python裝飾器的用法。
@app.route('/')
def index():
return render_template('index.html', async_mode=socketio.async_mode)
# 每次執行render_template函數時,渲染器都會將index.html的變量值用其實際值替代。


# 與前端創建 socket 鏈接後,啓動後臺線程
@socketio.on('connect', namespace='/test')
def test_connect():
global thread
with thread_lock:
if thread is None:
thread = socketio.start_background_task(target=background_thread)




if __name__ == '__main__':
socketio.run(app, debug=True)

index.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>CPU_and_MEM_Monitor</title>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript" src="https://cdn.bootcss.com/socket.io/1.5.1/socket.io.min.js"></script>
<!-- ECharts 3 引入 -->
<script src="http://echarts.baidu.com/dist/echarts.min.js"></script>
</head>

<body>
<!--爲ECharts準備一個具有大小(寬高)的Dom-->
<div id="CPU1" style="height:500px;border:1px solid #ccc;padding:10px;"></div>
<div id="CPU2" style="height:500px;border:1px solid #ccc;padding:10px;"></div>
<script type="text/javascript">

//--- 折柱 ---
// 3個全局變量:time、cpu一、cpu2
var time = ["","","","","","","","","",""],
cpu1 = [0,0,0,0,0,0,0,0,0,0],
cpu2 = [0,0,0,0,0,0,0,0,0,0]

//第一張echarts圖初始化
var CPU1 = echarts.init(document.getElementById('CPU1'));
CPU1.setOption({
title: {
text: 'CPU1'
},
tooltip: {},
legend: {
data:['cpu1']
},
xAxis: {
data: []
},
yAxis: {},
series: [{
name: 'cpu1',
type: 'line',
data: []
}]
});


//準備好的 callback 函數
var update_CPU1 = function (res) { //res是json格式的response對象

// 隱藏加載動畫
CPU1.hideLoading();

// 準備數據
time.push(res.data[0]);
cpu1.push(parseFloat(res.data[1]));
if (time.length >= 10){
time.shift();
cpu1.shift();
}

// 填入數據
CPU1.setOption({
xAxis: {
data: time
},
series: [{
name: 'cpu1', // 根據名字對應到相應的系列
data: cpu1
}]
});

};

//第二張echarts圖初始化
var CPU2 = echarts.init(document.getElementById('CPU2'));
CPU2.setOption({
title: {
text: 'CPU2'
},
tooltip: {},
legend: {
data:['cpu2']
},
toolbox: {
show : true,
feature : {
mark : {show: true},
dataView : {show: true, readOnly: false},
magicType : {show: true, type: ['line', 'bar', 'stack', 'tiled']},
restore : {show: true},
saveAsImage : {show: true}
}
},
calculable : true,
xAxis: {
data: []
},
yAxis: {},
series: [{
name: 'cpu2',
type: 'line',
smooth:true,
itemStyle: {normal: {areaStyle: {type: 'default'}}},
data: []
}]
});


//準備好的 callback 函數
var update_CPU2 = function (res) { //res是json格式的response對象

// 隱藏加載動畫
CPU2.hideLoading();

// 準備數據
time.push(res.data[0]);
cpu2.push(parseFloat(res.data[2]));
if (time.length >= 10){
time.shift();
cpu2.shift();
}

// 填入數據
CPU2.setOption({
xAxis: {
data: time
},
series: [{
name: 'cpu2', // 根據名字對應到相應的系列
data: cpu2
}]
});

};

// 首次顯示加載動畫
CPU1.showLoading();
CPU2.showLoading();

// 創建socket鏈接,等待服務器「推送」數據,用回調函數更新圖表
$(document).ready(function() {
namespace = '/test';
var socket = io.connect(location.protocol + '//' + document.domain + ':' + location.port + namespace);

socket.on('server_response', function(res) {
update_CPU1(res);
update_CPU2(res);
});

});

</script>
</body>
</html>
相關文章
相關標籤/搜索