minor fixes and updates
All checks were successful
Build Docs / changes (push) Successful in 5s
Build Docs / build-docs (push) Has been skipped
Build Docs / deploy-docs (push) Has been skipped

This commit is contained in:
Alexander Kalinovsky
2025-03-19 14:46:23 +07:00
parent f0db2b2830
commit fe0380f9f3
6 changed files with 53 additions and 50 deletions

View File

@@ -31,7 +31,11 @@ async def telegram_webhook(
return Response(status_code=400)
try:
await app.dp.feed_webhook_update(
app.bot, update, db_session=db_session, app=app
app.bot,
update,
db_session=db_session,
app=app,
**(request.state if request.state else {}),
)
except Exception:
logger.error("Error processing update", exc_info=True)

View File

@@ -24,24 +24,11 @@ class Config(BaseSettings):
def DATABASE_URI(self) -> str:
return f"postgresql+asyncpg://{self.DB_USER}:{self.DB_PASSWORD}@{self.DB_HOST}:{self.DB_PORT}/{self.DB_NAME}"
DOMAIN: str = "localhost"
@computed_field
@property
def API_DOMAIN(self) -> str:
if self.ENVIRONMENT == "local":
return self.DOMAIN
return f"{self.DOMAIN}"
@computed_field
@property
def API_URL(self) -> str:
if self.USE_NGROK:
return self.NGROK_URL
return f"https://{self.API_DOMAIN}"
API_PORT: int = 8000
TELEGRAM_WEBHOOK_URL: str = "http://localhost:8000"
TELEGRAM_BOT_SERVER: str = "https://api.telegram.org"
TELEGRAM_BOT_SERVER_IS_LOCAL: bool = False
TELEGRAM_BOT_TOKEN: str = "changethis"
ADMIN_TELEGRAM_ID: int

View File

@@ -1,6 +1,8 @@
from contextlib import asynccontextmanager
from typing import Callable, Any
from aiogram import Bot, Dispatcher
from aiogram.client.session.aiohttp import AiohttpSession
from aiogram.client.telegram import TelegramAPIServer
from aiogram.client.default import DefaultBotProperties
from aiogram.types import Message, BotCommand as AiogramBotCommand
from aiogram.utils.callback_answer import CallbackAnswerMiddleware
@@ -35,8 +37,8 @@ async def default_lifespan(app: "QBotApp"):
logger.info("qbot app started")
if app.lifespan:
async with app.lifespan(app):
yield
async with app.lifespan(app) as state:
yield state
else:
yield
@@ -88,8 +90,14 @@ class QBotApp[UserType: UserBase](FastAPI):
self.entity_metadata: EntityMetadata = user_class.entity_metadata
self.config = config
self.lifespan = lifespan
api_server = TelegramAPIServer.from_base(
self.config.TELEGRAM_BOT_SERVER,
is_local=self.config.TELEGRAM_BOT_SERVER_IS_LOCAL,
)
session = AiohttpSession(api=api_server)
self.bot = Bot(
token=self.config.TELEGRAM_BOT_TOKEN,
session=session,
default=DefaultBotProperties(parse_mode="HTML"),
)
@@ -124,7 +132,7 @@ class QBotApp[UserType: UserBase](FastAPI):
from .api_route.telegram import router as telegram_router
self.include_router(telegram_router, prefix="/api/telegram", tags=["telegram"])
self.include_router(telegram_router, prefix="/telegram", tags=["telegram"])
self.root_router = Router()
self.root_router._commands = self.bot_commands
self.command = self.root_router.command
@@ -177,6 +185,13 @@ class QBotApp[UserType: UserBase](FastAPI):
commands_captions[locale] = []
commands_captions[locale].append((command_name, description))
await self.bot.set_webhook(
url=f"{self.config.TELEGRAM_WEBHOOK_URL}/telegram/webhook",
drop_pending_updates=True,
allowed_updates=self.allowed_updates,
secret_token=self.bot_auth_token,
)
for locale, commands in commands_captions.items():
await self.bot.set_my_commands(
[
@@ -186,12 +201,7 @@ class QBotApp[UserType: UserBase](FastAPI):
language_code=None if locale == "default" else locale,
)
await self.bot.set_webhook(
url=f"{self.config.API_URL}/api/telegram/webhook",
drop_pending_updates=True,
allowed_updates=self.allowed_updates,
secret_token=self.bot_auth_token,
)
async def bot_close(self):
await self.bot.delete_webhook()
await self.bot.log_out()
await self.bot.close()

View File

@@ -67,14 +67,31 @@ class BotEntityMetaclass(SQLModelMetaclass):
descriptor_kwargs = attribute_value.__dict__.copy()
sm_descriptor = descriptor_kwargs.pop("sm_descriptor", None) # type: FieldInfo
if attribute_value.default is not None:
if sm_descriptor:
if (
sm_descriptor
attribute_value.default is not None
and sm_descriptor.default is PydanticUndefined
):
sm_descriptor.default = attribute_value.default
if (
attribute_value.default_factory is not None
and sm_descriptor.default_factory is PydanticUndefined
):
sm_descriptor.default_factory = (
attribute_value.default_factory
)
else:
sm_descriptor = Field(default=attribute_value.default)
if (
attribute_value.default is not None
or attribute_value.default_factory is not None
):
sm_descriptor = Field()
if attribute_value.default is not None:
sm_descriptor.default = attribute_value.default
if attribute_value.default_factory is not None:
sm_descriptor.default_factory = (
attribute_value.default_factory
)
if sm_descriptor:
namespace[annotation] = sm_descriptor
@@ -167,23 +184,6 @@ class BotEntityMetaclass(SQLModelMetaclass):
fields_descriptors=bot_fields_descriptors,
)
# descriptor_fields_sequence = [
# key
# for key, val in bot_fields_descriptors.items()
# if not (val.is_optional or val.name == "id" or val.name[:-3] == "_id")
# ]
# entity_descriptor: EntityDescriptor = namespace["bot_entity_descriptor"]
# if entity_descriptor.default_form.edit_field_sequence is None:
# entity_descriptor.default_form.edit_field_sequence = (
# descriptor_fields_sequence
# )
# for form in entity_descriptor.forms.values():
# if form.edit_field_sequence is None:
# form.edit_field_sequence = descriptor_fields_sequence
for field_descriptor in bot_fields_descriptors.values():
field_descriptor.entity_descriptor = namespace["bot_entity_descriptor"]

View File

@@ -102,6 +102,7 @@ class _BaseFieldDescriptor:
ep_child_field: str | None = None
dt_type: Literal["date", "datetime"] = "date"
default: Any = None
default_factory: Callable[[], Any] | None = None
@dataclass(kw_only=True)

View File

@@ -227,7 +227,9 @@ class Settings(metaclass=SettingsMetaclass):
)
return (
param.default
param.default_factory()
if param.default_factory
else param.default
if param.default
else (
[]
@@ -249,7 +251,6 @@ class Settings(metaclass=SettingsMetaclass):
session=session,
type_=setting.type_,
value=db_setting.value,
default=setting.default,
)
cls._loaded = True