Initial commit - cleaned repository
This commit is contained in:
168
backup-services/ai-writer/backend/test_ai_writer.py
Executable file
168
backup-services/ai-writer/backend/test_ai_writer.py
Executable file
@ -0,0 +1,168 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
AI Writer Service Test
|
||||
Claude API를 사용한 전문적인 뉴스 기사 생성 테스트
|
||||
"""
|
||||
import asyncio
|
||||
import httpx
|
||||
import json
|
||||
from datetime import datetime
|
||||
|
||||
# Service URL
|
||||
SERVICE_URL = "http://localhost:8019"
|
||||
|
||||
async def test_article_generation():
|
||||
"""인공지능 키워드로 기사 생성 테스트"""
|
||||
async with httpx.AsyncClient(timeout=120.0) as client:
|
||||
print("\n" + "="*70)
|
||||
print(" AI Writer Service - 전문 기사 생성 테스트 ")
|
||||
print("="*70)
|
||||
|
||||
print("\n📰 '인공지능' 키워드로 전문 기사 생성 중...")
|
||||
print("-" * 50)
|
||||
|
||||
# Generate article
|
||||
response = await client.post(
|
||||
f"{SERVICE_URL}/api/generate",
|
||||
json={
|
||||
"keyword": "인공지능",
|
||||
"limit": 5,
|
||||
"google_results_per_title": 3,
|
||||
"lang": "ko",
|
||||
"country": "KR",
|
||||
"style": "professional"
|
||||
}
|
||||
)
|
||||
|
||||
if response.status_code == 200:
|
||||
article = response.json()
|
||||
|
||||
print(f"\n✅ 기사 생성 완료!")
|
||||
print(f"\n📌 기사 ID: {article['news_id']}")
|
||||
print(f"📅 생성 시간: {article['created_at']}")
|
||||
print(f"\n📰 제목: {article['title']}")
|
||||
print(f"📝 요약: {article['summary']}")
|
||||
|
||||
print(f"\n🔍 카테고리: {', '.join(article['categories'])}")
|
||||
|
||||
# Print subtopics
|
||||
print(f"\n📚 소주제 ({len(article['subtopics'])}개):")
|
||||
for i, subtopic in enumerate(article['subtopics'], 1):
|
||||
print(f"\n [{i}] {subtopic['title']}")
|
||||
print(f" 문단 수: {len(subtopic['content'])}개")
|
||||
for j, paragraph in enumerate(subtopic['content'][:1], 1): # Show first paragraph only
|
||||
print(f" 미리보기: {paragraph[:150]}...")
|
||||
|
||||
# Print entities
|
||||
entities = article['entities']
|
||||
print(f"\n🏷️ 추출된 개체:")
|
||||
if entities['people']:
|
||||
print(f" 👤 인물: {', '.join(entities['people'])}")
|
||||
if entities['organizations']:
|
||||
print(f" 🏢 기관: {', '.join(entities['organizations'])}")
|
||||
if entities['groups']:
|
||||
print(f" 👥 단체: {', '.join(entities['groups'])}")
|
||||
if entities['countries']:
|
||||
print(f" 🌍 국가: {', '.join(entities['countries'])}")
|
||||
if entities.get('events'):
|
||||
events = entities['events']
|
||||
if events:
|
||||
print(f" 📅 이벤트 ({len(events)}개):")
|
||||
for evt in events[:3]: # 처음 3개만 표시
|
||||
if isinstance(evt, dict):
|
||||
evt_str = f" - {evt.get('name', '')}"
|
||||
if evt.get('date'):
|
||||
evt_str += f" [{evt['date']}]"
|
||||
if evt.get('location'):
|
||||
evt_str += f" @{evt['location']}"
|
||||
print(evt_str)
|
||||
else:
|
||||
# 이전 형식 (문자열) 지원
|
||||
print(f" - {evt}")
|
||||
if entities.get('keywords'):
|
||||
keywords = entities['keywords']
|
||||
if keywords:
|
||||
print(f" 🔑 키워드: {', '.join(keywords[:5])}" +
|
||||
("..." if len(keywords) > 5 else ""))
|
||||
|
||||
print(f"\n📊 참조 소스: {article.get('source_count', 0)}개")
|
||||
|
||||
# Save full article to file
|
||||
with open('generated_article.json', 'w', encoding='utf-8') as f:
|
||||
json.dump(article, f, ensure_ascii=False, indent=2)
|
||||
print(f"\n💾 전체 기사가 'generated_article.json'에 저장되었습니다.")
|
||||
|
||||
else:
|
||||
print(f"❌ 오류: {response.status_code}")
|
||||
print(f" 상세: {response.text}")
|
||||
|
||||
async def test_health_check():
|
||||
"""서비스 상태 확인"""
|
||||
async with httpx.AsyncClient() as client:
|
||||
print("\n" + "="*60)
|
||||
print("서비스 Health Check")
|
||||
print("="*60)
|
||||
|
||||
response = await client.get(f"{SERVICE_URL}/health")
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
print(f"✓ AI Writer 서비스 상태: {data.get('status', 'unknown')}")
|
||||
if 'services' in data:
|
||||
print(f" - News Aggregator: {data['services'].get('news_aggregator', 'unknown')}")
|
||||
print(f" - MongoDB: {data['services'].get('mongodb', 'unknown')}")
|
||||
print(f" - Claude API: {data['services'].get('claude_api', 'unknown')}")
|
||||
if 'error' in data:
|
||||
print(f" - Error: {data['error']}")
|
||||
else:
|
||||
print(f"✗ Health check 실패: {response.status_code}")
|
||||
|
||||
async def test_batch_generation():
|
||||
"""여러 키워드 일괄 처리 테스트"""
|
||||
async with httpx.AsyncClient(timeout=180.0) as client:
|
||||
print("\n" + "="*60)
|
||||
print("일괄 기사 생성 테스트")
|
||||
print("="*60)
|
||||
|
||||
keywords = ["AI 혁신", "디지털 전환", "스마트시티"]
|
||||
print(f"\n키워드: {', '.join(keywords)}")
|
||||
|
||||
response = await client.post(
|
||||
f"{SERVICE_URL}/api/generate/batch",
|
||||
json=keywords,
|
||||
params={"style": "analytical"}
|
||||
)
|
||||
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
print(f"\n✅ 처리 완료: {data['total_processed']}개")
|
||||
|
||||
if data['success']:
|
||||
print("\n성공한 기사:")
|
||||
for item in data['success']:
|
||||
print(f" - {item['keyword']}: {item['title'][:50]}...")
|
||||
|
||||
if data['errors']:
|
||||
print("\n실패한 항목:")
|
||||
for item in data['errors']:
|
||||
print(f" - {item['keyword']}: {item['error']}")
|
||||
else:
|
||||
print(f"❌ 오류: {response.status_code}")
|
||||
|
||||
async def main():
|
||||
"""메인 테스트 실행"""
|
||||
print("\n" + "="*70)
|
||||
print(" AI Writer Service Test Suite ")
|
||||
print(" RSS → Google Search → Claude AI 기사 생성 ")
|
||||
print("="*70)
|
||||
|
||||
# Run tests
|
||||
await test_health_check()
|
||||
await test_article_generation()
|
||||
# await test_batch_generation() # Optional: batch test
|
||||
|
||||
print("\n" + "="*70)
|
||||
print(" 테스트 완료 ")
|
||||
print("="*70)
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
Reference in New Issue
Block a user