#!/usr/bin/env dotnet-script // Direct KRX API Test // Purpose: Validate KRX API connectivity and data persistence // Step 1: Test direct API call → HTTP 200 + data // Step 2: Verify data saved to krx_imports table // Step 3: Repeat 5 times for reliability #r "nuget: System.Net.Http, 4.3.4" #r "nuget: Npgsql, 8.0.0" #r "nuget: Dapper, 2.0.151" using System; using System.Collections.Generic; using System.Net.Http; using System.Text.Json; using System.Threading.Tasks; using Npgsql; using Dapper; var config = new { ApiKey = Environment.GetEnvironmentVariable("KRX_OPENAPI") ?? "FB391C96F128419AAFB193AB73DD6B8263E0D021", BaseUrl = "https://openapi.krx.co.kr", Postgres = Environment.GetEnvironmentVariable("KARTSELL_POSTGRES") ?? "Host=127.0.0.1;Port=5432;Database=kartselldb;Username=kartsell;Password=kartsell4321@!" }; Console.WriteLine("════════════════════════════════════════════════════════════"); Console.WriteLine("🧪 KRX API 직접 호출 테스트 (API 완성도 검증)"); Console.WriteLine("════════════════════════════════════════════════════════════"); Console.WriteLine(""); // Test parameters var testDate = "20240102"; // 2024-01-02 var apiEndpoint = $"{config.BaseUrl}/svc/apis/idx/krx_dd_trd"; Console.WriteLine($"테스트 대상: {apiEndpoint}"); Console.WriteLine($"테스트 날짜: {testDate}"); Console.WriteLine(""); int successCount = 0; int failureCount = 0; for (int i = 1; i <= 5; i++) { Console.WriteLine($"[시도 {i}/5]"); try { using (var client = new HttpClient { Timeout = TimeSpan.FromSeconds(10) }) { // Build request var request = new HttpRequestMessage(HttpMethod.Post, apiEndpoint); request.Headers.Add("Authorization", $"Bearer {config.ApiKey}"); var body = new { basDd = testDate }; var json = JsonSerializer.Serialize(body); request.Content = new StringContent(json, System.Text.Encoding.UTF8, "application/json"); // Send request Console.WriteLine($" 요청 중... POST {apiEndpoint}"); var response = await client.SendAsync(request); if (response.IsSuccessStatusCode) { var content = await response.Content.ReadAsStringAsync(); var lines = content.Split('\n', StringSplitOptions.RemoveEmptyEntries); Console.WriteLine($" ✅ 성공! HTTP {(int)response.StatusCode}"); Console.WriteLine($" 응답: {lines.Length} 행"); if (lines.Length > 1) { Console.WriteLine($" 샘플: {lines[0].Substring(0, Math.Min(80, lines[0].Length))}"); } successCount++; // Save to DB try { await using var conn = new NpgsqlConnection(config.Postgres); await conn.OpenAsync(); var sql = @" INSERT INTO market_data.krx_imports (import_at, row_count, status, correlation_id) VALUES (@now, @count, 'SUCCESS', @corrId) ON CONFLICT (import_at, row_count) DO NOTHING "; var rows = await conn.ExecuteAsync(sql, new { now = DateTime.UtcNow, count = lines.Length - 1, // exclude header corrId = Guid.NewGuid().ToString() }); Console.WriteLine($" DB: {rows} 행 저장됨"); } catch (Exception ex) { Console.WriteLine($" ⚠️ DB 저장 실패: {ex.Message}"); } } else { Console.WriteLine($" ❌ 실패! HTTP {(int)response.StatusCode}"); var errorContent = await response.Content.ReadAsStringAsync(); Console.WriteLine($" 오류: {errorContent.Substring(0, Math.Min(100, errorContent.Length))}"); failureCount++; } } } catch (Exception ex) { Console.WriteLine($" ❌ 예외: {ex.Message}"); failureCount++; } Console.WriteLine(""); // Rate limit: wait 2 seconds between requests if (i < 5) { await Task.Delay(2000); } } Console.WriteLine("════════════════════════════════════════════════════════════"); Console.WriteLine("📊 테스트 결과"); Console.WriteLine("════════════════════════════════════════════════════════════"); Console.WriteLine($"성공: {successCount}/5"); Console.WriteLine($"실패: {failureCount}/5"); Console.WriteLine(""); if (successCount >= 3) { Console.WriteLine("✅ API 신뢰성 테스트 통과 (3/5 이상 성공)"); Console.WriteLine(" → 다음 단계: Hangfire 자동화 진행"); } else { Console.WriteLine("❌ API 신뢰성 미달 (3/5 미만)"); Console.WriteLine(" → 원인 분석 필요"); } Console.WriteLine(""); // Verify DB state try { await using var conn = new NpgsqlConnection(config.Postgres); await conn.OpenAsync(); var count = await conn.QuerySingleAsync( "SELECT COUNT(*) FROM market_data.krx_imports"); Console.WriteLine($"DB 최종 상태: {count} 행 저장됨"); } catch (Exception ex) { Console.WriteLine($"DB 조회 실패: {ex.Message}"); } Console.WriteLine(""); Console.WriteLine("테스트 완료.");