#!/usr/bin/env python3 """ Test BERTopic API endpoint on HF Spaces. """ import requests import json # HF Spaces URL API_URL = "https://zedwrkc-news-stance-detection.hf.space" # Test data TEST_ARTICLES = [ # 부동산 대책 { "article_id": 1, "title": "복기왕 \"15억 이상 주택은 욕망\"...서민들 가슴에 또 불지르나", "summary": "국회 국토교통위원회 여당 간사인 더불어민주당 복기왕 의원은 10·15 부동산 대책을 '사다리 걷어차기'라고 하는 건 실체가 없는 공격이라고 비판했다." }, { "article_id": 2, "title": "與복기왕 \"15억이 서민 아파트\"…국힘 \"집 못산 난 천민이냐\"", "summary": "국회 국토교통위 더불어민주당 간사인 복기왕 의원은 23일 10·15 부동산 대책에 대한 '사다리 걷어차기' 비판을 반박하는 과정에서 '15억 정도는 서민 아파트'라고 발언했다." }, { "article_id": 3, "title": "여야, 국토위서 이상경 '부동산 발언' 질타…사퇴촉구안엔 이견", "summary": "23일 국회 국토교통위원회 국정감사에서 10·15 부동산 대책과 관련해 논란이 된 이상경 국토교통부 제1차관에 대해 여야가 질타했다." }, # 한미 관세협상 { "article_id": 4, "title": "李대통령 \"관세협상, 시간 걸리더라도 합리적 결과 도달할 것\"", "summary": "이재명 대통령은 경주 APEC 정상회의에서 한미 관세협상이 타결될 가능성에 대해 합리적인 결과에 이르게 될 것이라고 확신한다고 말했다." }, { "article_id": 5, "title": "\"한·미는 동맹이고 상식 갖고 있어, 관세협상서 합리적 결과 나올 것\"", "summary": "한미 양국은 동맹 관계이며 상식을 갖고 있어 관세협상에서 합리적인 결과가 나올 것이라는 전망이 나왔다." }, { "article_id": 6, "title": "트럼프 관세 정책, 한미 협상 난항 예상", "summary": "트럼프 행정부의 관세 정책으로 인해 한미 무역 협상이 난항을 겪을 것으로 예상된다." }, # 북한 미사일 { "article_id": 7, "title": "북한 \"새무기체계 극초음속 비행체 시험발사\"...김정은 참관 안해", "summary": "북한이 미사일 무기체계인 극초음속 미사일을 시험 발사했다고 밝혔다." }, { "article_id": 8, "title": "북한 \"새로운 무기체계 발사...목표점 강타\"", "summary": "북한이 새로운 무기체계를 발사했으며 목표점을 정확히 강타했다고 발표했다." }, { "article_id": 9, "title": "북 \"극초음속 비행체 시험발사\"...김정은 참관 안 해", "summary": "북한이 극초음속 비행체를 시험발사했으나 김정은 위원장은 참관하지 않았다." }, # 여가부 폐지 { "article_id": 10, "title": "'본부'로 격하된 여가부...\"공룡 복지부에서 성평등 정책 묻힐 것\" 우려", "summary": "정부조직 개편안에 따라 여성가족부가 출범 21년 만에 독립부처에서 보건복지부 산하 본부로 격하될 위기에 처했다." }, { "article_id": 11, "title": "여가부 폐지 정부조직개편안 확정", "summary": "정부가 여성가족부를 폐지하고 보건복지부 산하 본부로 격하하는 정부조직개편안을 확정했다." }, { "article_id": 12, "title": "여성계, 여가부 폐지 반대 목소리", "summary": "여성계에서 여성가족부 폐지에 대한 반대 목소리가 높아지고 있다." }, # 해군 전력모함 { "article_id": 13, "title": "해군 \"3만t급 한국형 유·무인 전력모함 확보 추진\"", "summary": "해군이 유인기 운용 위주의 경항모 대신 3만톤급 한국형 유무인 전력모함을 2030년대 후반까지 확보하는 계획을 보고했다." }, { "article_id": 14, "title": "해군 \"경항모 대신 3만 톤급 전력모함 확보 추진\"", "summary": "해군이 경항모 대신 유무인 겸용 전력모함 확보를 추진한다고 밝혔다." }, { "article_id": 15, "title": "해군, 경항모 대신 전력모함 건조 추진", "summary": "해군이 경항모 건조 계획을 전력모함으로 변경하여 추진하고 있다." } ] def test_bertopic_api(): """Test BERTopic API endpoint.""" print("="*100) print("BERTopic API Test") print("="*100) print(f"\nAPI URL: {API_URL}") print(f"Test articles: {len(TEST_ARTICLES)}") # Check health first print("\n⏳ Checking API health...") try: response = requests.get(f"{API_URL}/health", timeout=10) if response.status_code == 200: print("✅ API is healthy") health = response.json() print(f" Embedding model: {health.get('embedding_model')}") else: print(f"❌ Health check failed: {response.status_code}") return except Exception as e: print(f"❌ Cannot connect to API: {e}") return # Call BERTopic endpoint print("\n⏳ Calling /bertopic-clustering...") payload = { "articles": TEST_ARTICLES, "min_topic_size": 2, "nr_topics": "auto" } try: response = requests.post( f"{API_URL}/bertopic-clustering", json=payload, timeout=120 ) if response.status_code != 200: print(f"❌ API call failed: {response.status_code}") print(f" Error: {response.text}") return result = response.json() print("✅ BERTopic clustering completed!") # Display results print(f"\n{'='*100}") print("RESULTS") print(f"{'='*100}") print(f"\n📊 Statistics:") print(f" Total topics: {result['total_topics']}") print(f" Total articles: {result['total_articles']}") print(f" Outliers: {result['outliers']}") print(f" Processing time: {result['processing_time_seconds']}s") print(f"\n{'─'*100}") print("Topics:") print(f"{'─'*100}") for topic in result['topics']: topic_id = topic['topic_id'] topic_title = topic['topic_title'] count = topic['article_count'] if topic_id == -1: print(f"\n🔸 Topic -1 (Outliers): {count} articles") print(f" Article IDs: {topic['article_ids']}") continue print(f"\n🔹 Topic {topic_id}: {topic_title} ({count} articles)") # Keywords if topic['keywords']: print(f" Keywords:") for kw in topic['keywords']: print(f" - {kw['keyword']:30} (score: {kw['score']:.3f})") # Articles print(f" Article IDs: {topic['article_ids']}") # Show article titles for article_id in topic['article_ids']: article = next((a for a in TEST_ARTICLES if a['article_id'] == article_id), None) if article: print(f" - [{article_id}] {article['title'][:60]}...") # Summary print(f"\n\n{'='*100}") print("SUMMARY") print(f"{'='*100}") print(f"\n✅ BERTopic successfully clustered {result['total_articles']} articles") print(f" - {result['total_topics']} distinct topics found") print(f" - {result['outliers']} outliers (acceptable)") print(f" - Processing time: {result['processing_time_seconds']}s") print(f"\n💡 Expected topics:") print(f" - 부동산 대책") print(f" - 한미 관세 협상") print(f" - 북한 미사일 시험 발사") print(f" - 여가부 폐지") print(f" - 해군 전력모함 확보 추진") print(f"\n📊 Actual topics:") for topic in result['topics']: if topic['topic_id'] != -1: print(f" - Topic {topic['topic_id']}: {topic['topic_title']}") print("="*100) except Exception as e: print(f"❌ Error: {e}") import traceback traceback.print_exc() if __name__ == "__main__": print("\n⏳ Waiting for HF Spaces to build (2-3 minutes)...") print("Press Enter when build is complete...") input() test_bertopic_api()