簡體   English   中英

'promisify' (async/await) 使用 Python 中的 pymsteams 向 Microsoft Teams 發送消息

[英]'promisify' (async/await) sending a message to Microsoft Teams using pymsteams in Python

我正在使用logging模塊在我的 Python 腳本中向 MS Teams 發送大量消息。 不幸的是,這很慢,所以我想在消息中添加異步/等待功能。

這是我的記錄器模塊(有些簡化):

from logging import StreamHandler
import pymsteams

class TeamsHandler(StreamHandler):

    def __init__(self, channel_url):
        StreamHandler.__init__(self)
        self.channel_url = channel_url
        self.client = pymsteams.connectorcard(self.channel_url)

    def emit(self, record):
        msg = self.format(record)
        self.client.text(msg)
        try:
            self.client.send()
        except:
            print(f"{msg} could not be sent to Teams")

然后您將在常規腳本中使用它:

import logging
from TeamsHandler import TeamsHandler #the module above

my_logger = logging.getLogger('TestLogging')
my_logger.setLevel(logging.DEBUG)
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.DEBUG)
my_logger.addHandler(console_handler)

CHANNEL_ID = "https://outlook.office.com/webhook/your-big-number"
teamshandler = TeamsHandler(CHANNEL_ID)
teamshandler.setFormatter(logging.Formatter('%(levelname)s %(message)s'))
teamshandler.setLevel(logging.DEBUG)
my_logger.addHandler(teamshandler)
for i in range(1,100):
    my_logger.error(f"this is an error [{i}]")
    my_logger.info(f"this is an info [{i}]")
do_something_else()

我怎樣才能使do_something_else立即(幾乎)執行,而不必等待 200 條消息進入 Teams?

我嘗試在TeamsHandler模塊中添加一些asyncawait關鍵字,但沒有嘗試成功,所以我沒有將它們放在問題中。 如果不是完整的解決方案,很高興得到一些指示。

理想情況下,隨着腳本的進行,消息的順序應該保持不變。

如果pymsteams不支持 async/await,那么將async添加到您的函數中並不會真正幫助您,因為您最終仍會從pymsteams調用同步代碼。 即使它確實支持異步/等待,它仍然無法工作,因為您是從 Python 日志記錄 API 內部調用它們,這本身不是異步的。 async/await 不能神奇地將同步代碼轉換為 async,程序必須全面使用 async/await。

但是,如果您需要在后台運行某些東西的異步執行,您可以使用線程來代替。 例如,為日志創建一個專用線程,例如:

class TeamsHandler(StreamHandler):
    def __init__(self, channel_url):
        super().__init__()
        self.channel_url = channel_url
        self.client = pymsteams.connectorcard(self.channel_url)
        self.queue = queue.Queue()
        self.thread = threading.Thread(target=self._worker)
        self.thread.start()
        # shutdown the worker at process exit
        atexit.register(self.queue.put, None)

    def _worker(self):
        while True:
            record = self.queue.get()
            if record is None:
                break
            msg = self.format(record)
            self.client.text(msg)
            try:
                self.client.send()
            except:
                print(f"{msg} could not be sent to Teams")

    def emit(self, record):
        # enqueue the record to log and return control to the caller
        self.queue.put(record)

當然,這有一個缺點,即如果日志記錄后端出現問題,您的程序可能會遠遠超過您在日志中看到的內容 - 但是當您刪除日志記錄和執行之間的同步時,情況總是如此。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM