diff --git a/bot.py b/bot.py index 7f0577a..54a9fa8 100644 --- a/bot.py +++ b/bot.py @@ -36,7 +36,7 @@ async def init() -> web.Application: app = web.Application() subapps: List[str, web.Application] = [ ('/health/', web_handlers.health_app), - ('/tg/webhooks', web_handlers.tg_updates_app), + ('/tg/webhooks/', web_handlers.tg_updates_app), ] for prefix, subapp in subapps: subapp['bot'] = bot diff --git a/utils/__init__.py b/utils/__init__.py index 976134d..ec315cd 100644 --- a/utils/__init__.py +++ b/utils/__init__.py @@ -1,3 +1,2 @@ -from . import db_api from . import misc -from . import redis +from .db import db_api, redis diff --git a/utils/redis/__init__.py b/utils/db/__init__.py similarity index 100% rename from utils/redis/__init__.py rename to utils/db/__init__.py diff --git a/utils/db_api/__init__.py b/utils/db/db_api/__init__.py similarity index 100% rename from utils/db_api/__init__.py rename to utils/db/db_api/__init__.py diff --git a/utils/db_api/storages/__init__.py b/utils/db/db_api/storages/__init__.py similarity index 51% rename from utils/db_api/storages/__init__.py rename to utils/db/db_api/storages/__init__.py index 5b34153..71c8864 100644 --- a/utils/db_api/storages/__init__.py +++ b/utils/db/db_api/storages/__init__.py @@ -1 +1,2 @@ +from .mysql import MysqlConnection from .sqlite import SqliteConnection diff --git a/utils/db_api/storages/basestorage/__init__.py b/utils/db/db_api/storages/basestorage/__init__.py similarity index 100% rename from utils/db_api/storages/basestorage/__init__.py rename to utils/db/db_api/storages/basestorage/__init__.py diff --git a/utils/db_api/storages/basestorage/storage.py b/utils/db/db_api/storages/basestorage/storage.py similarity index 100% rename from utils/db_api/storages/basestorage/storage.py rename to utils/db/db_api/storages/basestorage/storage.py diff --git a/utils/db/db_api/storages/mysql/__init__.py b/utils/db/db_api/storages/mysql/__init__.py new file mode 100644 index 0000000..83caad3 --- /dev/null +++ b/utils/db/db_api/storages/mysql/__init__.py @@ -0,0 +1 @@ +from .storage import MysqlConnection diff --git a/utils/db/db_api/storages/mysql/storage.py b/utils/db/db_api/storages/mysql/storage.py new file mode 100644 index 0000000..42c04e4 --- /dev/null +++ b/utils/db/db_api/storages/mysql/storage.py @@ -0,0 +1,83 @@ +import asyncio +from typing import Any, Dict, List, Optional, Type, TypeVar, Union + +import aiomysql +from loguru import logger + +from data import config +from ..basestorage.storage import RawConnection + +T = TypeVar("T") + + +# noinspection DuplicatedCode +class MysqlConnection(RawConnection): + connection_pool = None + + @staticmethod + async def __make_request( + sql: str, + params: Union[tuple, List[tuple]] = None, + fetch: bool = False, + mult: bool = False, + retries_count: int = 5 + ) -> Optional[Union[List[Dict[str, Any]], Dict[str, Any]]]: + if MysqlConnection.connection_pool is None: + MysqlConnection.connection_pool = await aiomysql.create_pool(**config.mysql_info) + async with MysqlConnection.connection_pool.acquire() as conn: + conn: aiomysql.Connection = conn + async with conn.cursor(aiomysql.DictCursor) as cur: + cur: aiomysql.DictCursor = cur + for i in range(retries_count): + try: + if isinstance(params, list): + await cur.executemany(sql, params) + else: + await cur.execute(sql, params) + except (aiomysql.OperationalError, aiomysql.InternalError) as e: + logger.error(f'Found error [{e}] [{sql}] [{params}] retrying [{i}/{retries_count}]') + if 'Deadlock found' in str(e): + await asyncio.sleep(1) + else: + break + if fetch: + if mult: + r = await cur.fetchall() + else: + r = await cur.fetchone() + return r + else: + await conn.commit() + + @staticmethod + def _convert_to_model(data: Optional[dict], model: Type[T]) -> Optional[T]: + if data is not None: + return model(**data) + else: + return None + + @staticmethod + async def _make_request( + sql: str, + params: Union[tuple, List[tuple]] = None, + fetch: bool = False, + mult: bool = False, + model_type: Type[T] = None + ) -> Optional[Union[List[T], T]]: + raw = await MysqlConnection.__make_request(sql, params, fetch, mult) + if raw is None: + if mult: + return [] + else: + return None + else: + if mult: + if model_type is not None: + return [MysqlConnection._convert_to_model(i, model_type) for i in raw] + else: + return list(raw) + else: + if model_type is not None: + return MysqlConnection._convert_to_model(raw, model_type) + else: + return raw diff --git a/utils/db_api/storages/sqlite/__init__.py b/utils/db/db_api/storages/sqlite/__init__.py similarity index 100% rename from utils/db_api/storages/sqlite/__init__.py rename to utils/db/db_api/storages/sqlite/__init__.py diff --git a/utils/db_api/storages/sqlite/storage.py b/utils/db/db_api/storages/sqlite/storage.py similarity index 97% rename from utils/db_api/storages/sqlite/storage.py rename to utils/db/db_api/storages/sqlite/storage.py index c766c50..c6e3789 100644 --- a/utils/db_api/storages/sqlite/storage.py +++ b/utils/db/db_api/storages/sqlite/storage.py @@ -7,7 +7,7 @@ from loguru import logger from ..basestorage.storage import RawConnection T = TypeVar("T") -db_title = Path(__file__).parent.parent.parent.parent.parent / 'data' / 'db.db' # db file supposed to be in data folder +db_title = Path(__file__).parent.parent.parent.parent.parent / 'data' / 'db.db' # db file supposed to be in data folder class SqliteDBConn: diff --git a/utils/db/redis/__init__.py b/utils/db/redis/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/utils/redis/consts.py b/utils/db/redis/consts.py similarity index 100% rename from utils/redis/consts.py rename to utils/db/redis/consts.py diff --git a/utils/db_api/consts.py b/utils/db_api/consts.py deleted file mode 100644 index 4210608..0000000 --- a/utils/db_api/consts.py +++ /dev/null @@ -1,47 +0,0 @@ -import asyncio -from typing import Optional, Dict, Any, Union, List - -import aiomysql - -from data import config - - -class RawConnection: - connection_pool = None - - @staticmethod - async def _make_request( - sql: str, - params: Union[tuple, List[tuple]] = None, - fetch: bool = False, - mult: bool = False, - retries_count: int = 5 - ) -> Optional[Union[List[Dict[str, Any]], Dict[str, Any]]]: - if RawConnection.connection_pool is None: - RawConnection.connection_pool = await aiomysql.create_pool(**config.mysql_info) - async with RawConnection.connection_pool.acquire() as conn: - conn: aiomysql.Connection = conn - async with conn.cursor(aiomysql.DictCursor) as cur: - cur: aiomysql.DictCursor = cur - for i in range(retries_count): - try: - if isinstance(params, list): - await cur.executemany(sql, params) - else: - await cur.execute(sql, params) - except aiomysql.OperationalError as e: - if 'Deadlock found' in str(e): - await asyncio.sleep(1) - except aiomysql.InternalError as e: - if 'Deadlock found' in str(e): - await asyncio.sleep(1) - else: - break - if fetch: - if mult: - r = await cur.fetchall() - else: - r = await cur.fetchone() - return r - else: - await conn.commit() diff --git a/web_handlers/tg_updates.py b/web_handlers/tg_updates.py index c2e0c7c..749644e 100644 --- a/web_handlers/tg_updates.py +++ b/web_handlers/tg_updates.py @@ -16,4 +16,4 @@ async def execute(req: web.Request) -> web.Response: return web.Response() -tg_updates_app.add_routes([web.post('/{token}', execute)]) +tg_updates_app.add_routes([web.post('/bot/{token}', execute)])