사용자의 전체 라이브러리 async-only 요청에 따라 OpinetClient 하나로 통합했다. 기존 동기 클래스에 있던 파서와 정규화 모델을 유지하고 I/O를 native async로 바꿨다. 공통 AsyncTokenBucket을 주입해 TPS를 합산한다. 디버그는 공유 HTTP 객체 교체 대신 ContextVar를 사용하고 VWorld 지역 코드 캐시는 코루틴 대신 완료된 값만 저장한다.
이 문서는 이 프로젝트의 구조적 결정을 결정 시점 순서로 누적한다. 결정이 뒤집힐 때는 새 항목을 추가하고, 옛 항목은 지우지 않은 채 (supersedes: 위 항목)으로 표시한다.
- 상태: accepted
- 날짜: 2026-04-30
한국석유공사가 배포한 공공데이터 활용 가이드북 PDF에는 무료 API가 22종으로 명시되어 있지만, 공식 사이트의 오픈 API 페이지(openApiInfo.do, 인증 파라미터 certkey)에는 5종만 등재되어 있다. PDF의 나머지 17종은 다른 게이트웨이(custApiInfo.do 계열, 인증 파라미터 추정 code)로 보이며 명세 페이지가 없어 실제 호출이 동작하는지 검증할 방법이 없다.
공식 오픈 API 페이지에 등재된 5개 엔드포인트(avgAllPrice.do, lowTop10.do, aroundAll.do, detailById.do, areaCode.do)만 OpinetClient의 안정 구현 대상으로 삼는다. PDF 가이드북의 나머지 17종은 opinet.experimental.OpinetExperimentalClient로 완전히 분리하고 "Unverified" 경고를 남긴다.
- 명세 페이지가 있는 API만 파싱 규칙과 fixture를 신뢰성 있게 만들 수 있다.
- 검증 안 된 API를 안정 클라이언트에 섞으면 사용자가 실제 동작 여부를 구분할 수 없다.
- 두 게이트웨이의 인증 파라미터(
certkeyvs 추정code)가 달라 동일 클라이언트로 묶기 어렵다.
OpinetClient는 5개 엔드포인트만 보장하고, 나머지는opinet.experimental에서 별도 경고와 함께 제공된다.- PR을 통한 실제 키 기반 검증 보고를 받아 검증되면 안정 API로 승격하는 경로를 열어둔다.
- 상태: accepted
- 날짜: 2026-04-30
오피넷 API는 모든 좌표를 KATEC(오피넷 자체 TM 좌표계, m 단위)으로 주고받는다. 반면 이 라이브러리를 쓰는 downstream 애플리케이션은 일반적으로 WGS84(위경도) 좌표를 사용한다. 좌표계를 하나만 제공하면 다른 쪽 값이 필요한 호출자가 매번 직접 pyproj 변환을 다시 구현해야 한다.
응답 모델은 KATEC 원시 좌표(katec_x, katec_y)와 변환된 WGS84 좌표(lon, lat)를 항상 함께 필드로 채운다. 사용자 입력도 WGS84(lon/lat) 또는 KATEC(katec_x/katec_y) 어느 쪽이든 받고, 내부에서 오피넷 API가 요구하는 KATEC으로 변환해 호출한다. 변환은 src/opinet/coords.py에서 pyproj를 직접 사용하며 별도 좌표 DTO/adapter로 감싸지 않는다.
- 오피넷 실측 좌표와 ±10m 이내로 일치함을 검증한
pyprojTM 변환식을 이미 보유하고 있다. - KATEC 원본값을 버리면 재현/디버깅(오피넷 공식 응답과의 직접 비교)이 어려워진다.
- 두 좌표계를 모두 노출하면 downstream이 자체 좌표 변환 로직을 중복 구현하지 않아도 된다.
- 모든 좌표 포함 응답 모델(
Station,StationDetail등)에lon/lat/katec_x/katec_y와lon_lat/katec_xy튜플 헬퍼가 존재한다. - KATEC proj 정의 문자열이 README에 고정 문서화되어 변환식 변경 시 반드시 함께 갱신해야 한다.
- 상태: accepted
- 날짜: 2026-04-30
오피넷의 시도 코드(AREA_CD, 예: 01=서울)는 행정안전부 표준 법정동코드(예: 11=서울)와 완전히 다른 별도 체계다. 두 체계 사이에는 산술 규칙이 없다(오피넷은 단순 일련번호, 법정동은 광역시/도/특별자치시별 구간이 다름). 강원특별자치도·전북특별자치도 출범으로 법정동 시도코드가 각각 51/52로 변경된 이력도 있어, 자동 변환 공식을 만들면 조용히 틀린 값을 낼 위험이 있다. 시군구 4자리 코드(SIGUNCD)는 시도 코드보다 더 근거가 얕아, 코드값만으로 법정동 시군구코드와 일치한다고 가정할 수 없다.
시도(2자리) 레벨은 17개 항목 고정 매핑 테이블(opinet_sido_to_bjd() / bjd_sido_to_opinet())로 하드코딩해서 제공한다. 시군구(4자리) 레벨은 산술/사전 매핑을 시도하지 않고, 필요하면 vworld.VworldClient.search_district(..., category="L2") 결과의 id/title을 명시적으로 매칭하는 별도 헬퍼(opinet.vworld.resolve_sigungu_bjd_code)로만 해결한다.
- 시도 17개는 유한하고 안정적이라 표로 고정해도 유지보수 부담이 작다.
- 시군구는 표로 고정하기엔 근거(공식 매핑 문서)가 없고, 오검증된 값을 배포하면 조용한 데이터 오류로 이어진다.
- VWorld 검색 결과의 이름 매칭은 최소한 사람이 검증 가능한 근거를 남긴다.
AreaCode.bjd_sido_prefix는 항상 신뢰 가능하지만, 시군구 5자리 법정동코드는resolve_sigungu_bjd_code()를 통한 명시 조회 없이는 얻을 수 없다.- README와 AGENTS.md 양쪽에 "시군구 코드는 자동 변환 불가"라는 경고를 중복 고지해야 한다.