feat(global): init structure
This commit is contained in:
2
src/utils/__init__.py
Normal file
2
src/utils/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
||||
from .env import env
|
||||
from .logging import logger
|
||||
23
src/utils/config.py
Normal file
23
src/utils/config.py
Normal file
@@ -0,0 +1,23 @@
|
||||
from pymongo import MongoClient
|
||||
|
||||
from utils.db.models.config import DynamicConfig, DynamicConfigBase
|
||||
|
||||
from . import env
|
||||
|
||||
|
||||
def load_config() -> DynamicConfigBase:
|
||||
client = MongoClient(env.db.connection_url)
|
||||
|
||||
db = client[env.db.db_name]
|
||||
config_dict = db.config.find_one()
|
||||
|
||||
if config_dict is None:
|
||||
return DynamicConfigBase()
|
||||
|
||||
config_dict.pop("_id", None)
|
||||
|
||||
return DynamicConfigBase.model_validate(config_dict)
|
||||
|
||||
|
||||
dconfig = DynamicConfig.get_or_create
|
||||
config: DynamicConfigBase = load_config()
|
||||
19
src/utils/db/__init__.py
Normal file
19
src/utils/db/__init__.py
Normal file
@@ -0,0 +1,19 @@
|
||||
from beanie import init_beanie
|
||||
from motor.motor_asyncio import AsyncIOMotorClient
|
||||
|
||||
from utils.env import env
|
||||
|
||||
client = AsyncIOMotorClient(env.db.connection_url)
|
||||
|
||||
|
||||
async def init_db():
|
||||
from .models import (
|
||||
DynamicConfig,
|
||||
)
|
||||
|
||||
await init_beanie(
|
||||
database=client[env.db.db_name],
|
||||
document_models=[
|
||||
DynamicConfig,
|
||||
],
|
||||
)
|
||||
1
src/utils/db/models/__init__.py
Normal file
1
src/utils/db/models/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from .config import DynamicConfig
|
||||
27
src/utils/db/models/config.py
Normal file
27
src/utils/db/models/config.py
Normal file
@@ -0,0 +1,27 @@
|
||||
from beanie import Document
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
|
||||
class BotConfig(BaseModel):
|
||||
admins: list[int] = []
|
||||
|
||||
|
||||
class DynamicConfigBase(BaseModel):
|
||||
bot: BotConfig = Field(default_factory=BotConfig)
|
||||
|
||||
|
||||
class DynamicConfig(DynamicConfigBase, Document):
|
||||
class Settings:
|
||||
name = "config"
|
||||
|
||||
async def save(self): # noqa
|
||||
await super().save() # noqa
|
||||
|
||||
@classmethod
|
||||
async def get_or_create(cls):
|
||||
config = await cls.find_one()
|
||||
if not config:
|
||||
config = cls()
|
||||
await config.save()
|
||||
|
||||
return config
|
||||
42
src/utils/env.py
Normal file
42
src/utils/env.py
Normal file
@@ -0,0 +1,42 @@
|
||||
from pydantic import SecretStr
|
||||
from pydantic_settings import BaseSettings, SettingsConfigDict
|
||||
|
||||
|
||||
class BotSettings(BaseSettings):
|
||||
token: SecretStr
|
||||
|
||||
|
||||
class DatabaseSettings(BaseSettings):
|
||||
host: str = "mongodb"
|
||||
port: int = 27017
|
||||
user: SecretStr = "user"
|
||||
password: SecretStr = "password"
|
||||
db_name: str = "prod"
|
||||
connection_params: str = "?authSource=admin"
|
||||
scripts_connection_url: str = "mongodb://user:password@localhost:27017/"
|
||||
|
||||
@property
|
||||
def connection_url(self) -> str:
|
||||
return f"mongodb://{self.user.get_secret_value()}:{self.password.get_secret_value()}@{self.host}:{self.port}/{self.db_name}{self.connection_params}"
|
||||
|
||||
|
||||
class LogSettings(BaseSettings):
|
||||
level: str = "INFO"
|
||||
show_time: bool = False
|
||||
console_width: int = 150
|
||||
|
||||
|
||||
class Settings(BaseSettings):
|
||||
bot: BotSettings
|
||||
db: DatabaseSettings
|
||||
log: LogSettings
|
||||
|
||||
model_config = SettingsConfigDict(
|
||||
case_sensitive=False,
|
||||
env_file=".env",
|
||||
env_nested_delimiter="__",
|
||||
extra="ignore",
|
||||
)
|
||||
|
||||
|
||||
env = Settings() # noqa
|
||||
37
src/utils/logging.py
Normal file
37
src/utils/logging.py
Normal file
@@ -0,0 +1,37 @@
|
||||
import logging
|
||||
|
||||
from rich.console import Console
|
||||
from rich.logging import RichHandler
|
||||
|
||||
from . import env
|
||||
|
||||
console = Console(
|
||||
width=env.log.console_width,
|
||||
color_system="auto",
|
||||
force_terminal=True,
|
||||
)
|
||||
|
||||
|
||||
def setup_logging():
|
||||
from aiogram.dispatcher import router
|
||||
from dishka.integrations import aiogram
|
||||
|
||||
logging.basicConfig(
|
||||
level=env.log.level,
|
||||
format=None, # noqa
|
||||
datefmt=None,
|
||||
handlers=[
|
||||
RichHandler(
|
||||
console=console,
|
||||
markup=True,
|
||||
rich_tracebacks=True,
|
||||
tracebacks_show_locals=True,
|
||||
omit_repeated_times=False,
|
||||
show_time=env.log.show_time,
|
||||
tracebacks_suppress=[router, aiogram],
|
||||
)
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
Reference in New Issue
Block a user