aigc_article_html.py 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. """Read the latest article visualization HTML from the external AIGC database."""
  2. from __future__ import annotations
  3. from functools import lru_cache
  4. from typing import Any
  5. from sqlalchemy import create_engine, text
  6. from sqlalchemy.pool import QueuePool
  7. from supply_infra.config import get_infra_settings
  8. @lru_cache(maxsize=1)
  9. def _get_aigc_readonly_engine() -> Any:
  10. settings = get_infra_settings()
  11. if not all(
  12. (
  13. settings.aigc_readonly_mysql_host,
  14. settings.aigc_readonly_mysql_user,
  15. settings.aigc_readonly_mysql_database,
  16. )
  17. ):
  18. raise RuntimeError("AIGC read-only MySQL connection is not configured")
  19. return create_engine(
  20. settings.aigc_readonly_mysql_url,
  21. poolclass=QueuePool,
  22. pool_size=2,
  23. max_overflow=0,
  24. pool_timeout=10,
  25. pool_recycle=1800,
  26. pool_pre_ping=True,
  27. connect_args={
  28. "connect_timeout": 10,
  29. "read_timeout": 30,
  30. "write_timeout": 30,
  31. },
  32. )
  33. def get_latest_article_html(channel_content_id: str) -> str | None:
  34. statement = text(
  35. """
  36. SELECT t2.html
  37. FROM aigc_task_input_usage t1
  38. JOIN aigc_task_callback_data t2
  39. ON t2.task_instance_id = t1.task_instance_id
  40. WHERE t1.biz_unique_id = :channel_content_id
  41. ORDER BY t2.id DESC
  42. LIMIT 1
  43. """
  44. )
  45. with _get_aigc_readonly_engine().connect() as connection:
  46. value = connection.scalar(
  47. statement,
  48. {"channel_content_id": channel_content_id},
  49. )
  50. if value is None:
  51. return None
  52. if isinstance(value, bytes):
  53. return value.decode("utf-8", errors="replace")
  54. return str(value)