feat(app): add main application entrypoint and service coordinator

This commit is contained in:
mamad
2026-08-27 19:54:15 +03:30
parent 3b3935fd6f
commit fbbdf5c91b
+86
View File
@@ -0,0 +1,86 @@
import asyncio
import logging
import signal
import os
from dotenv import load_dotenv
from db.database import init_db, close_db_pool
from db.repository import Repository
from core.metrics import start_metrics_server
from core.llm import LLMClient
from services.ai_processor import AIProcessor
from services.collector import CollectorService
from services.admin_bot import AdminBotService
from services.publisher import PublisherService
# Load environment variables
load_dotenv()
# Configure logging
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [%(levelname)s] %(name)s: %(message)s"
)
logger = logging.getLogger("copykar.main")
async def main():
logger.info("Starting Copykar System...")
# 1. Start Prometheus metrics server
metrics_port = int(os.getenv("METRICS_PORT", "8000"))
start_metrics_server(metrics_port)
# 2. Initialize Database schema
await init_db()
logger.info("Database schema initialized.")
repo = Repository()
llm = LLMClient()
# 3. Create Services
admin_bot = AdminBotService(repo=repo)
ai_processor = AIProcessor(repo=repo, llm=llm)
# Wrap AI processor to automatically push reviewed posts to admin review channel
original_process_post = ai_processor.process_post
async def process_and_notify(post_id: int):
post = await original_process_post(post_id)
if post:
await admin_bot.send_review_post(post.id)
return post
ai_processor.process_post = process_and_notify
collector = CollectorService(repo=repo, ai_processor=ai_processor)
publisher = PublisherService(repo=repo)
# 4. Start all services
await admin_bot.start()
await collector.start()
await publisher.start()
logger.info("All Copykar services are active and running.")
# Graceful shutdown event
stop_event = asyncio.Event()
loop = asyncio.get_running_loop()
for sig in (signal.SIGINT, signal.SIGTERM):
try:
loop.add_signal_handler(sig, stop_event.set)
except NotImplementedError:
pass # Windows or specific platforms
try:
await stop_event.wait()
except (asyncio.CancelledError, KeyboardInterrupt):
pass
finally:
logger.info("Shutting down Copykar services...")
await collector.stop()
await publisher.stop()
await admin_bot.stop()
await close_db_pool()
logger.info("Copykar cleanly shut down.")
if __name__ == "__main__":
asyncio.run(main())