iT邦幫忙

0

python 如何開啟flask後而繼續跑main的程式?

  • 分享至 

  • xImage
import flask
import time
app = flask.Flask(__name__)

@app.route("/")
@app.route("/timecount")
def start():
    #同事要啟動擷取監控
    return start
    
@app.route("/timestop")
def end ():
     #同事要關閉擷取監控
    return timestop

if __name__ == '__main__':
  host,port = "127.0.0.2",3000
  app.run(host,port)
  
  #接下來下面要跑一直跑監控程式
  """
  監控程式,收到要開始跟結束把中間擷取的監控狀態回傳
  """

因為一打開flask當server就會整個變成阻塞狀態,
所以請問如何在當server時既能接收API又不影響主程,
並把value傳達到主程讓他可以隨時開始與停止?

更新:
就是我要用python做一個監控系統,
同時要開放API功能讓同事可以透過API擷取監控內的狀態回傳。

看更多先前的討論...收起先前的討論...
froce iT邦大師 1 級 ‧ 2023-03-09 12:41:48 檢舉
先說你為啥要這樣做。感覺你這是要做什麼但是根本不知道怎麼做,亂寫出來的東西。

要使用者追蹤的話用GA就好。
https://www.webguide.nat.gov.tw/News_Content.aspx?n=531&s=2935
ccutmis iT邦高手 2 級 ‧ 2023-03-09 12:59:19 檢舉
應該是想要透過路由做計時? 也可能是透過路由做別的事情?...
froce iT邦大師 1 級 ‧ 2023-03-09 13:15:29 檢舉
> 應該是想要透過路由做計時? 也可能是透過路由做別的事情?...

我猜是網頁停留時間啦。
alanotmt iT邦新手 4 級 ‧ 2023-03-09 13:16:16 檢舉
我有更新了問題請問froce大有理解嗎? 我不是要追蹤使用者
alien663 iT邦研究生 5 級 ‧ 2023-03-09 15:22:24 檢舉
用fork?
把API跟你的監控程式分開來不要寫在同一個program
另外app.run 就會把 main block 在那邊了
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
0
黃彥儒
iT邦高手 1 級 ‧ 2023-03-09 13:42:03

你需要讓你要跑的程式由其他 線程或是執行緒 執行。
簡單的辦法就是你自己再寫一個Python然後Flask下指令給另外一個程式,可能透過 socket 或類似的方法。
所以監控是另一個程式跑的,他會維護監控的訊息和狀態,Flask是對他下命令的角色。

alanotmt iT邦新手 4 級 ‧ 2023-03-09 13:52:14 檢舉

這我有用過multiprocessing
Queue()的方式做轉拋values
但這個在監控時還要主動queue.get()的方式去抓回API現在的狀態覺得有點反智,想說有沒有其他方式可以API主動發給我主程接收又同時在跑監控。

黃彥儒 iT邦高手 1 級 ‧ 2023-03-09 15:01:44 檢舉

.....你開心就好

1
froce
iT邦大師 1 級 ‧ 2023-03-09 14:01:44
from flask import Flask
import time
import asyncio

app = Flask(__name__)

class MonitorService:
    counter = 0
    
    async def run(self):
        while True:
            await asyncio.sleep(1)
            self.counter += 1
            
    @property
    def show(self):
        return self.counter
            
ms = MonitorService()

@app.route("/")
def hello_world():
    print(ms.show)
    return f"<p>{ms.show}</p>"

async def main():
    loop = asyncio.get_event_loop()
    host,port = "127.0.0.2",3000
    app_task = loop.run_in_executor(None, lambda:app.run(host,port))
    service_task = asyncio.create_task(ms.run())
    await asyncio.gather(service_task, app_task)

if __name__ == '__main__':
    asyncio.run( main())

這樣?
雖然我也覺得該用2隻程式跑比較正確。

alanotmt iT邦新手 4 級 ‧ 2023-03-09 14:27:18 檢舉

froce大有辦法讓user訪問時清空counter嗎?
我現在就是差在這步,B程api被訪問時我的A程監控系統卻不會知道。
B程能拿A程的資料,這邊沒問題。

froce iT邦大師 1 級 ‧ 2023-03-09 14:44:00 檢舉

要設定的話我會建議乖乖用thread/multiprocessing的Queue...要不然你要自己控制lock。
這個完全不能保證會不會死鎖,所以我不繼續寫下去害人。
我這只是寫好玩的。

0
I code so I am
iT邦高手 1 級 ‧ 2023-03-10 11:51:51

可以轉個方向,在Flask內執行非同步的工作。要實施監控,可寫一支爬蟲程式不斷瀏覽http://localhost:5000/start ,即可監控網站。
範例如下:

# pip install flask[async]
   
from flask import Flask
import time
import asyncio

app = Flask(__name__)

async def task1(expr):
    await asyncio.sleep(1) #time.sleep(1)
    return eval(expr)

# not work
@app.route("/async/<expr>")
async def getdata(expr):
    data = await task1(expr)
    print("the answer =", data)
    return {"input": expr, "answer": data}
    
@app.route('/')
def index():
   return 'Hello World'

if __name__ == '__main__':
   app.run()

我要發表回答

立即登入回答