[英]'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
模塊中添加一些async
和await
關鍵字,但沒有嘗試成功,所以我沒有將它們放在問題中。 如果不是完整的解決方案,很高興得到一些指示。
理想情況下,隨着腳本的進行,消息的順序應該保持不變。
如果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.