Files
g2s-aggregator/app/workers/waybill_email_sender.py
T
2026-05-24 00:55:09 +03:00

92 lines
3.1 KiB
Python

"""Background worker that e-mails CDEK waybill PDFs."""
import asyncio
import signal
import httpx
import structlog
from app.adapters.delivery_providers.cdek.auth import CDEKAuthClient
from app.adapters.delivery_providers.cdek.client import CDEKClient
from app.adapters.email import SMTPEmailSender
from app.adapters.postgres.engine import (
create_postgres_engine,
create_postgres_session_factory,
)
from app.config import Settings, get_settings
from app.repositories.order import OrderRepository
from app.runtime.logging import configure_logging
from app.services.waybill_email_sender import WaybillEmailSenderService
logger = structlog.get_logger(__name__)
async def _run(settings: Settings, stop_event: asyncio.Event) -> None:
http_client = httpx.AsyncClient(timeout=settings.adapter.cdek_timeout_seconds)
auth_client = CDEKAuthClient(
http_client=http_client,
base_url=settings.adapter.cdek_base_url,
client_id=settings.adapter.cdek_client_id,
client_secret=settings.adapter.cdek_client_secret,
timeout_seconds=settings.adapter.cdek_timeout_seconds,
)
cdek_client = CDEKClient(
http_client=http_client,
auth_client=auth_client,
base_url=settings.adapter.cdek_base_url,
timeout_seconds=settings.adapter.cdek_timeout_seconds,
retry_attempts=settings.adapter.cdek_retry_attempts,
retry_backoff_seconds=settings.adapter.cdek_retry_backoff_seconds,
)
email_sender = SMTPEmailSender(
smtp_host=settings.email.smtp_host,
smtp_port=settings.email.smtp_port,
username=settings.email.username,
password=settings.email.password,
from_address=settings.email.from_address,
use_tls=settings.email.use_tls,
timeout_seconds=settings.email.timeout_seconds,
)
engine = create_postgres_engine(settings.postgres)
session_factory = create_postgres_session_factory(engine)
repository = OrderRepository(session_factory=session_factory)
service = WaybillEmailSenderService(
order_repository=repository,
waybill_downloader=cdek_client,
email_sender=email_sender,
batch_size=settings.waybill_email_sender.batch_size,
)
logger.info(
"waybill_email_sender_started",
interval_seconds=settings.waybill_email_sender.interval_seconds,
batch_size=settings.waybill_email_sender.batch_size,
)
try:
await service.run_forever(
interval_seconds=settings.waybill_email_sender.interval_seconds,
stop_event=stop_event,
)
finally:
await http_client.aclose()
await engine.dispose()
logger.info("waybill_email_sender_stopped")
async def main() -> None:
configure_logging()
settings = get_settings()
stop_event = asyncio.Event()
loop = asyncio.get_running_loop()
for sig in (signal.SIGTERM, signal.SIGINT):
try:
loop.add_signal_handler(sig, stop_event.set)
except NotImplementedError:
pass
await _run(settings, stop_event)
if __name__ == "__main__":
asyncio.run(main())