run_main_fan_batch.py 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. #!/usr/bin/env python3
  2. """显式选矿的本地完整Agent联调;隔离数据库、模拟PDF接口、禁止结果推送。"""
  3. import argparse
  4. import asyncio
  5. from datetime import datetime
  6. import json
  7. import os
  8. from pathlib import Path
  9. import sys
  10. from zoneinfo import ZoneInfo
  11. ROOT = Path(__file__).resolve().parents[1]
  12. sys.path.insert(0, str(ROOT))
  13. async def run(args, output):
  14. from extensions.main_fan.batch import BatchRunner
  15. from runtime.environment import RuntimeEnvironment
  16. async with RuntimeEnvironment(prewarm=False, billing_retry=False):
  17. runner = BatchRunner(output, args.mock_pdf, cache_root=args.cache_dir,
  18. progress=lambda data: print(json.dumps(data, ensure_ascii=False), flush=True))
  19. state = await runner.run({'dept_ids': args.dept_id or [], 'all_producing_mines': args.all_producing_mines,
  20. 'snapshot_id': args.snapshot_id,
  21. 'reassess': args.reassess,
  22. 'cutoff': args.cutoff, 'lookback_days': 40, 'user_name': 'main-fan-batch-local'})
  23. print(json.dumps({'status': state['status'], 'output': str(output),
  24. 'index': str(output / 'index.html'), 'mine_count': len(state['mines']), 'publish': False}, ensure_ascii=False), flush=True)
  25. return 0 if state['status'] == 'completed' else 1
  26. def main():
  27. parser = argparse.ArgumentParser(description=__doc__)
  28. selection = parser.add_mutually_exclusive_group(required=True)
  29. selection.add_argument('--dept-id', action='append', help='正常生产煤矿的真实部门编号,可重复指定')
  30. selection.add_argument('--all-producing-mines', action='store_true', help='显式选择本批次全部正常生产煤矿,联调不使用')
  31. parser.add_argument('--mock-pdf', type=Path, required=True, help='原有测试PDF,不修改内容')
  32. parser.add_argument('--snapshot-id', help='使用已有冻结清单;默认重新取得deptTree')
  33. parser.add_argument('--cutoff', help='冻结的北京时间截止时刻,默认批次启动时刻')
  34. parser.add_argument('--output', type=Path, help='批次输出目录;再次指定同目录可恢复未完成项')
  35. parser.add_argument('--cache-dir', type=Path, help='可选独立报告档案目录')
  36. parser.add_argument('--reassess', action='store_true', help='在同一输出目录重新分析,保留旧报告并复用同批次已有数据')
  37. parser.add_argument('--allow-large-batch', action='store_true', help='显式解除联调最多两个矿的保护')
  38. args = parser.parse_args()
  39. if (args.all_producing_mines or len(args.dept_id or []) > 2) and not args.allow_large_batch:
  40. parser.error('本地联调默认最多两个矿;大批次必须另行显式启用')
  41. if not args.mock_pdf.is_file():
  42. parser.error('测试PDF不存在')
  43. stamp = datetime.now(ZoneInfo('Asia/Shanghai')).strftime('%Y%m%d_%H%M%S')
  44. output = (args.output or ROOT / 'outputs/main_fan_batches' / stamp).resolve()
  45. output.mkdir(parents=True, exist_ok=True)
  46. os.environ.update({'DEEP_AGENT_ENV_PRIORITY': 'process', 'DB_DIALECT': 'sqlite',
  47. 'DB_SQLITE_PATH': str(output / 'runtime/business.sqlite'), 'CHECKPOINTER': 'sqlite',
  48. 'CHECKPOINT_DB_PATH': str(output / 'runtime/checkpoints.sqlite'),
  49. 'RESULT_PLATFORM_ENABLED': '0', 'MAIN_FAN_AUTO_PUBLISH': '0',
  50. 'MAIN_FAN_LOCAL_BATCH_ENABLED': '0', 'MAIN_FAN_ALLOW_MANUAL_CACHE': '0',
  51. 'MAIN_FAN_TARGETS_FILE': '', 'LOG_LEVEL': 'WARNING'})
  52. (output / 'runtime').mkdir(exist_ok=True)
  53. raise SystemExit(asyncio.run(run(args, output)))
  54. if __name__ == '__main__':
  55. main()