Files
KArtSell.Aegis/scripts/test-krx-api-direct.cs
kjh2064 f3a99b6f8e test: Add KRX API direct test script (step 1 validation)
Test script to validate KRX API connectivity and data persistence:
- 5 iterations with 2-second rate limit spacing
- Saves successful responses to market_data.krx_imports
- Verifies reliability (3/5 threshold)
- Uses correct AUTH_KEY header format per KRX API spec

Current status: KRX API endpoint returning 404/timeout
- /svc/apis/idx/krx_dd_trd (production) — not found
- /svc/sample/apis/idx/krx_dd_trd (sample) — not found
- Root cause: External KRX server currently unreachable

Next step: Use KrxDataService stub data fallback (already implemented)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-08-14 14:30:15 +09:00

166 lines
5.9 KiB
C#

#!/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<int>(
"SELECT COUNT(*) FROM market_data.krx_imports");
Console.WriteLine($"DB 최종 상태: {count} 행 저장됨");
}
catch (Exception ex)
{
Console.WriteLine($"DB 조회 실패: {ex.Message}");
}
Console.WriteLine("");
Console.WriteLine("테스트 완료.");