update poetry.lock

This commit is contained in:
Dmitry Afanasyev 2023-09-12 01:20:59 +03:00
parent 8b2fb805b5
commit 2d34a94eed
4 changed files with 3261 additions and 1074 deletions

View File

@ -1,5 +1,6 @@
import asyncio import asyncio
import os import os
import time
from asyncio import Queue, sleep from asyncio import Queue, sleep
from dataclasses import dataclass from dataclasses import dataclass
from functools import cached_property from functools import cached_property
@ -13,13 +14,14 @@ from app.constants import API_PREFIX
from settings.config import Settings from settings.config import Settings
class Bot: class BotApplication:
def __init__(self, settings: Settings) -> None: def __init__(self, settings: Settings, start_with_webhook: bool = False) -> None:
self.application: Application = ( # type: ignore self.application: Application = ( # type: ignore
Application.builder().token(token=settings.TELEGRAM_API_TOKEN).build() Application.builder().token(token=settings.TELEGRAM_API_TOKEN).build()
) )
self.add_handlers() self.add_handlers()
self.settings = settings self.settings = settings
self.start_with_webhook = start_with_webhook
async def set_webhook(self) -> None: async def set_webhook(self) -> None:
await self.application.initialize() await self.application.initialize()
@ -32,8 +34,18 @@ class Bot:
@staticmethod @staticmethod
async def help_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: async def help_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
"""Send a message when the command /help is issued.""" """Send a message when the command /help is issued."""
if update.message: if update.message:
await update.message.reply_text('Help!') await asyncio.sleep(10)
await update.message.reply_text(
'Help!',
disable_notification=True,
api_kwargs={
"text": "Hello World",
"date": int(time.time()) + 30,
"schedule_date": int(time.time()) + 30,
},
)
return None return None
def add_handlers(self) -> None: def add_handlers(self) -> None:
@ -59,15 +71,15 @@ class Bot:
@dataclass @dataclass
class BotQueue: class BotQueue:
bot: Bot bot_app: Application # type: ignore[type-arg]
queue: Queue = asyncio.Queue() # type: ignore queue: Queue = asyncio.Queue() # type: ignore[type-arg]
async def put_updates_on_queue(self, request: Request) -> Response: async def put_updates_on_queue(self, request: Request) -> Response:
""" """
Listen {WEBHOOK_PATH}/{TELEGRAM_WEB_TOKEN} path and proxy post request to bot Listen {WEBHOOK_PATH}/{TELEGRAM_WEB_TOKEN} path and proxy post request to bot
""" """
data = await request.json() data = await request.json()
tg_update = Update.de_json(data=data, bot=self.bot.application.bot) tg_update = Update.de_json(data=data, bot=self.bot_app.bot)
self.queue.put_nowait(tg_update) self.queue.put_nowait(tg_update)
return Response(status_code=HTTPStatus.ACCEPTED) return Response(status_code=HTTPStatus.ACCEPTED)
@ -75,5 +87,6 @@ class BotQueue:
async def get_updates_from_queue(self) -> None: async def get_updates_from_queue(self) -> None:
while True: while True:
update = await self.queue.get() update = await self.queue.get()
await self.bot.application.process_update(update) print(update)
await sleep(0.1) await self.bot_app.process_update(update)
await sleep(0)

View File

@ -1,11 +1,11 @@
import asyncio
import sys import sys
from functools import cached_property
from fastapi import FastAPI from fastapi import FastAPI
from fastapi.responses import UJSONResponse from fastapi.responses import UJSONResponse
from loguru import logger from loguru import logger
from app.core.bot import Bot, BotQueue from app.core.bot import BotApplication, BotQueue
from app.routers import api_router from app.routers import api_router
from settings.config import Settings, get_settings from settings.config import Settings, get_settings
@ -19,18 +19,21 @@ logger.add(
class Application: class Application:
def __init__(self, settings: Settings) -> None: def __init__(self, settings: Settings, bot_app: BotApplication) -> None:
self.app = FastAPI( self.app = FastAPI(
title='Health check bot', title='Health check bot',
description='Bot which check all services are working', description='Bot which check all services are working',
version='0.0.1', version='0.0.3',
docs_url=f'{settings.WEBHOOK_PATH}/docs', docs_url=f'{settings.WEBHOOK_PATH}/docs',
redoc_url=f'{settings.WEBHOOK_PATH}/redocs', redoc_url=f'{settings.WEBHOOK_PATH}/redocs',
openapi_url=f'{settings.WEBHOOK_PATH}/api/openapi.json', openapi_url=f'{settings.WEBHOOK_PATH}/api/openapi.json',
default_response_class=UJSONResponse, default_response_class=UJSONResponse,
) )
self.app.state.settings = settings self.app.state.settings = settings
self.app.state.queue = BotQueue(bot_app=bot_app.application)
self.bot_app = bot_app
self.settings = settings self.settings = settings
self.app.include_router(api_router) self.app.include_router(api_router)
self.configure_hooks() self.configure_hooks()
@ -38,26 +41,28 @@ class Application:
def fastapi_app(self) -> FastAPI: def fastapi_app(self) -> FastAPI:
return self.app return self.app
@cached_property
def bot(self) -> Bot:
return Bot(self.settings)
def set_bot_queue(self) -> None:
self.app.state.queue = BotQueue(bot=self.bot)
def configure_hooks(self) -> None: def configure_hooks(self) -> None:
self.app.add_event_handler("startup", self.bot.set_webhook) if self.bot_app.start_with_webhook:
# self.app.add_event_handler("startup", self.bot.polling) # noqa: E800 self.app.add_event_handler("startup", self.bot_app.polling)
self.app.add_event_handler("startup", self.set_bot_queue) else:
self.app.add_event_handler("startup", self._on_start_up)
self.app.add_event_handler("shutdown", self.bot.delete_webhook) self.app.add_event_handler("shutdown", self._on_shutdown)
self.app.add_event_handler("shutdown", self.bot.shutdown)
async def _on_start_up(self) -> None:
await self.bot_app.set_webhook()
loop = asyncio.get_event_loop()
loop.create_task(self.app.state.queue.get_updates_from_queue())
async def _on_shutdown(self) -> None:
await asyncio.gather(self.bot_app.delete_webhook(), self.bot_app.shutdown())
def create_app(settings: Settings | None = None) -> FastAPI: def create_app(settings: Settings | None = None) -> FastAPI:
settings = settings or get_settings() settings = settings or get_settings()
bot_app = BotApplication(settings=settings, start_with_webhook=settings.START_WITH_WEBHOOK)
return Application(settings=settings).fastapi_app return Application(settings=settings, bot_app=bot_app).fastapi_app
def main() -> None: def main() -> None:

4169
poetry.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -6,68 +6,112 @@ authors = ["Dmitry Afanasyev <Balshbox@gmail.com>"]
[tool.poetry.dependencies] [tool.poetry.dependencies]
fastapi = "^0.95" fastapi = "^0.101"
python-telegram-bot = {version = "^20.3", extras=["ext"]} python-telegram-bot = {version = "^20.5", extras=["ext"]}
python = "^3.11" python = "^3.11"
python-dotenv = "^1.0" python-dotenv = "^1.0"
httpx = "^0.24" httpx = "^0.24"
loguru = "^0.7" loguru = "^0.7"
pydantic = "^1.10.7" pydantic = "^2.3"
gunicorn = "^20.1" gunicorn = "^21.2"
uvicorn = "^0.22" uvicorn = "^0.23"
wheel = "^0.40" wheel = "^0.41"
orjson = "^3.8" orjson = "^3.9"
websocket-client = "^1.6"
requests = "^2.31"
selenium = "^4.11"
tls-client = "^0.2"
pypasser = "^0.0.5"
names = "^0.3"
colorama = "^0.4"
curl_cffi = "^0.5"
aiohttp = "^3.8.5"
flask = "^2.3"
flask_cors = "^4.0"
flask-babel = "^3.1"
streamlit = "^1.26"
fake-useragent = "^1.2"
twocaptcha = "^0.0.1"
pymailtm = "^1.1"
Levenshtein = "^0.21"
retrying = "^1.3"
mailgw_temporary_email = "^0.0.2"
pycryptodome = "^3.18"
random-password-generator = "^2.2"
numpy = "^1.25"
tornado = "^6.3"
PyExecJS = "^1.5"
browser_cookie3 = "^0.19"
[tool.poetry.dev-dependencies] [tool.poetry.dev-dependencies]
factory-boy = "^3.2" factory-boy = "^3.3"
Faker = "^18.3.0" Faker = "^19"
ipython = "^8.13" ipython = "^8.14"
safety = "^2.3" safety = "^2.3"
pip-audit = "^2.5" pip-audit = "^2.6"
yamllint = "^1.30" yamllint = "^1.32"
tomlkit = "^0.11.7" tomlkit = "^0.12"
bandit = "^1.7" bandit = "^1.7"
aresponses = "^2.1" aresponses = "^2.1"
pyupgrade = "^3.4" pyupgrade = "^3.10"
isort = "^5.12" isort = "^5.12"
black = "^23.3" black = "^23.3"
mypy = "^1.2" mypy = "^1.5"
types-PyMySQL = "^1.0" types-PyMySQL = "^1.0"
types-python-dateutil = "^2.8" types-python-dateutil = "^2.8"
pytest = "^7.2" pytest = "^7.4"
pytest-asyncio = "^0.21" pytest-asyncio = "^0.21"
pytest-deadfixtures = "^2.2" pytest-deadfixtures = "^2.2"
pytest-repeat = "^0.9"
pytest-testmon = "^2.0" pytest-testmon = "^2.0"
pytest-mock = "^3.10" pytest-mock = "^3.11"
pytest-cov = "^4.0" pytest-cov = "^4.1"
pytest-timeout = "^2.1" pytest-timeout = "^2.1"
pytest-timeouts = "^1.2"
pytest-sugar = "^0.9" pytest-sugar = "^0.9"
pytest-clarity = "^1.0" pytest-clarity = "^1.0"
pytest-env = "^0.8" pytest-env = "^0.8"
nest-asyncio = "^1.5" nest-asyncio = "^1.5"
pytest-html = "^3.2"
pytest-randomly = "^3.15"
pytest-split = "^0.8"
pytest-freezegun = "^0.4"
pytest-socket = "^0.6"
assertpy = "^1.1"
autoflake = "^1.7" coverage = "^7.3"
flake8 = "^5.0.4"
autoflake = "2.2"
flake8 = "^6.1"
flake8-logging-format = "^0.9" flake8-logging-format = "^0.9"
flake8-comprehensions = "^3.11" flake8-comprehensions = "^3.14"
flake8-eradicate = "^1.4" flake8-eradicate = "^1.5"
flake8-deprecated = "^2.0"
flake8-pytest-style = "^1.7" flake8-pytest-style = "^1.7"
flake8-aaa = "^0.14" flake8-aaa = "^0.16"
flake8-bugbear = "^23.3" flake8-bugbear = "^23.7"
flake8-warnings = "^0.4"
flake8-debugger = "^4.1" flake8-debugger = "^4.1"
flake8-expression-complexity = "^0.0.11" flake8-annotations-complexity = "^0.0.8"
flake8-fixme = "^1.1" flake8-fixme = "^1.1"
flake8-simplify = "^0.20" flake8-simplify = "^0.20"
flake8-variables-names = "^0.0.5" flake8-variables-names = "^0.0.6"
flake8-bandit = "^4.1" flake8-bandit = "^4.1"
flake8-tidy-imports = "^4.8" flake8-tidy-imports = "^4.10"
flake8-noqa = "^1.3"
flake8-useless-assert = "^0.4"
flake8-mock = "^0.4"
flake8-jira-todo-checker = "^0.6"
flake8-comments = "^0.1"
flake8-newspaper-style = "^0.4"
[tool.isort] [tool.isort]