我需要建议。
我有一个机器人(使用远程机器人编写)和一个 API(Flask),它们在两个线程中运行并同时安静地工作。该机器人通过轮询启动。
API 处理来自多个地址的传入 POST 请求。
现在我正在使用 aiogram 重写机器人。 我知道你不能混合异步和线程,但是这两个模块的同时操作存在困难。机器人或 API 都可以工作。
有哪些选项可以与 Flask 和 Aiogram 交朋友,或者我们应该放弃使用 Flask 并以不同的方式处理请求?
我还阅读了有关 webhooks 的选项,似乎你可以在那里捕获 POST 请求,然后不需要 Flask。
我尝试了在不同线程中运行的选项:
import threading
import time
from time import sleep
from flask import Flask,request
from flask_restful import Api, Resource
import config
import asyncio,hashlib,requests,threading,time
import logs
from aiogram import Bot, Dispatcher, executor, types
from asyncio import new_event_loop, set_event_loop
app = Flask(__name__)
api = Api(app)
dp = Dispatcher(Bot(token=config.bot_token))
@dp.message_handler(commands="start")
async def message_start(message: types.Message):
await message.answer("HI")
@app.route('/test', methods=['POST'])
def get_test():
data = request.get_json()
print (data)
return ("ok")
def app_run():
while True:
try:
app.run()
except Exception as ex:
print(ex)
def bot_polling():
try:
executor.start_polling(dp, skip_updates=True)
set_event_loop(new_event_loop())
except Exception as ex:
print(ex)
bot_thread = threading.Thread(target=bot_polling)
bot_thread.daemon = True
bot_thread.start()
app_thread = threading.Thread(target=app_run)
app_thread.daemon = True
app_thread.start()
if __name__ == "__main__":
while True:
try:
sleep(1)
except KeyboardInterrupt:
break
我还尝试使用“on_startup”内置 aiogram 来使用异步:
import threading
import time
from time import sleep
from flask import Flask, jsonify, request
from flask_restful import Api, Resource
import config
import asyncio,hashlib,requests,threading,time
import logs
from aiogram import Bot, Dispatcher, executor, types
from asyncio import new_event_loop, set_event_loop
app = Flask(__name__)
api = Api(app)
dp = Dispatcher(Bot(token=config.bot_token))
@dp.message_handler(commands="start")
async def message_start(message: types.Message):
print("hi")
await message.answer("HI")
@app.route('/test', methods=['POST'])
def get_test():
data = request.get_json()
print (data)
return ("ok")
async def is_enabled():
while True:
await app.run()
async def on_startup(x):
asyncio.create_task(is_enabled())
if __name__ == '__main__':
executor.start_polling(dispatcher=dp, skip_updates=True, on_startup=on_startup)
最适合您的选择是 https://docs.aiogram.dev/en/latest/examples/webhook_example.html webhooks。
如果您将使用数据库的逻辑放在一个单独的模块中,我们将通过该模块与烧瓶和机器人进行通信,那么应该没有问题。然后用这样的拐杖运行它们:)
两个模块并行工作:
flask_api.py
def main():
app = Flask(__name__)
api = Api(app)
api.init_app(app)
app.run(port=PORT, host=HOST)
if __name__ == '__main__':
main()
aiogram_bot.py
async def main():
bot = Bot(token=TOKEN_TG)
dp = Dispatcher(bot)
await dp.skip_updates()
await dp.start_polling()
if __name__ == '__main__':
asyncio.run(main())
我这样运行它们:
app.py
import multiprocessing
import subprocess
api_process = multiprocessing.Process(
target=subprocess.run,
kwargs={
'args': f'{PYTHON_PATH} flask_api.py',
'shell': True
})
bot_process = multiprocessing.Process(
target=subprocess.run,
kwargs={
'args': f'{PYTHON_PATH} aiogram_bot.py',
'shell': True
})
if __name__ == '__main__':
api_process.start()
bot_process.start()
我知道已经很晚了,但我是这样修复的:
import asyncio
async def start_raid_bot():
dp_bot1 = Dispatcher()
dp_bot1.include_router(raid_router)
await dp_bot1.start_polling(bot1)
async def start_trend_bot():
dp_bot2 = Dispatcher()
dp_bot2.include_router(router_trend_bot)
await dp_bot2.start_polling(bot2)
async def main():
asyncio.create_task(confirm_payment_and_inform_user())
task_bot1 = asyncio.create_task(start_raid_bot())
task_bot2 = asyncio.create_task(start_trend_bot())
await task_bot1
await task_bot2
if __name__ == "__main__":
asyncio.run(main())