"""Entry point for Spore Agent Commons node. Supports two modes: - Full mode (default): koi-net FullNode + Spore API - Standalone mode (--standalone): FastAPI only, no koi-net """ import asyncio import logging import sys import uvicorn from spore_node.config import SporeConfig, build_node_config from spore_node.db.connection import init_pool, close_pool from spore_node.api.main import mount_routers, create_standalone_app logging.basicConfig( level=logging.INFO, format="%(asctime)s [%(name)s] %(levelname)s: %(message)s", ) log = logging.getLogger("spore_node") def run_standalone(cfg: SporeConfig) -> None: """Run in standalone mode — FastAPI only.""" app = create_standalone_app(cfg) uvicorn.run(app, host="0.0.0.0", port=cfg.node_port, log_level="info") def run_full(cfg: SporeConfig) -> None: """Run in full mode — koi-net node + Spore API.""" from spore_node.node import create_node node = create_node(cfg) # Mount Spore routers on the koi-net FastAPI app mount_routers(node.server.app) # Initialize DB before node starts async def _init_db(): await init_pool(cfg.database_url) asyncio.get_event_loop().run_until_complete(_init_db()) log.info(f"Starting Spore Commons node on port {cfg.node_port}") try: node.run() finally: asyncio.get_event_loop().run_until_complete(close_pool()) def main() -> None: cfg = SporeConfig() if "--standalone" in sys.argv: log.info("Running in standalone mode (no koi-net)") run_standalone(cfg) else: log.info("Running in full mode (koi-net + Spore API)") run_full(cfg) if __name__ == "__main__": main()