@nomadamas/k-skill 0.5.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/skills/komsa-ferry-info/instruction.md +54 -0
- package/skills/komsa-ferry-info/scripts/komsa_ferry_info.py +76 -0
- package/skills/komsa-ferry-info/skill.json +6 -0
- package/skills/railway-timetable/instruction.md +40 -0
- package/skills/railway-timetable/references/AUTOMATION-LEGAL-STATEMENT.md +5 -0
- package/skills/railway-timetable/references/DISCLAIMER.md +7 -0
- package/skills/railway-timetable/references/TRADEMARK-LEGAL-STATEMENT.md +3 -0
- package/skills/{ktx-booking/scripts/ktx_booking.py → railway-timetable/scripts/ktx_backend.py} +0 -0
- package/skills/{ktx-booking → railway-timetable}/scripts/ktx_timetable.py +0 -2
- package/skills/railway-timetable/scripts/railway_timetable.py +95 -0
- package/skills/railway-timetable/scripts/railway_timetable.py.lock +27 -0
- package/skills/railway-timetable/skill.json +8 -0
- package/skills/real-estate-search/instruction.md +22 -2
- package/skills/real-estate-search/scripts/nationwide_daily_report.py +545 -0
- package/skills/store-longevity-radar/scripts/__pycache__/store_longevity_download.cpython-312.pyc +0 -0
- package/skills/ktx-booking/instruction.md +0 -61
- package/skills/ktx-booking/references/AUTOMATION-LEGAL-STATEMENT.md +0 -10
- package/skills/ktx-booking/references/DISCLAIMER.md +0 -14
- package/skills/ktx-booking/references/TRADEMARK-LEGAL-STATEMENT.md +0 -9
- package/skills/ktx-booking/skill.json +0 -8
- package/skills/srt-booking/instruction.md +0 -75
- package/skills/srt-booking/references/AUTOMATION-LEGAL-STATEMENT.md +0 -25
- package/skills/srt-booking/references/DISCLAIMER.md +0 -13
- package/skills/srt-booking/references/TRADEMARK-LEGAL-STATEMENT.md +0 -9
- package/skills/srt-booking/scripts/srt_booking.py +0 -171
- package/skills/srt-booking/scripts/srt_booking.py.lock +0 -207
- package/skills/srt-booking/skill.json +0 -8
- /package/skills/{ktx-booking/scripts/ktx_booking.py.lock → railway-timetable/scripts/ktx_backend.py.lock} +0 -0
package/package.json
CHANGED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# KOMSA 연안여객선 정보 조회
|
|
2
|
+
|
|
3
|
+
## What this skill does
|
|
4
|
+
|
|
5
|
+
한국해양교통안전공단(KOMSA) MTIS Open API를 통해 연안여객선 운항 일정, 선박 제원, 기항지, 면허항로, 운항항로, 운항상태를 조회한다. 예매·결제·로그인 자동화는 하지 않는다.
|
|
6
|
+
|
|
7
|
+
## Public access path
|
|
8
|
+
|
|
9
|
+
기본 경로는 hosted/self-host `k-skill-proxy`의 좁은 read-only route다.
|
|
10
|
+
|
|
11
|
+
- 공식 포털: <https://mtisopenapi.komsa.or.kr/>
|
|
12
|
+
- 운항 일정: `https://mtisopenapi.komsa.or.kr/eopt/api/oprt-schd-info`
|
|
13
|
+
- 운항노선: `https://mtisopenapi.komsa.or.kr/eopt/api/oprt-line-info`
|
|
14
|
+
- 선박 제원: `https://mtisopenapi.komsa.or.kr/eopt/api/psnshp-spec`
|
|
15
|
+
- 프록시: `GET /v1/komsa/ferry/{dataset}`
|
|
16
|
+
|
|
17
|
+
지원 dataset은 `schedules`, `vessels`, `ports`, `license-routes`, `operation-routes`, `status`다. upstream `serviceKey`는 프록시 서버의 `KOMSA_MTIS_API_KEY` 또는 `KSKILL_KOMSA_MTIS_API_KEY`로만 주입한다.
|
|
18
|
+
|
|
19
|
+
## Workflow
|
|
20
|
+
|
|
21
|
+
Helper 실행:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npx -y @nomadamas/k-skill@0 exec komsa-ferry-info scripts/komsa_ferry_info.py -- \
|
|
25
|
+
schedules --date 20260824 --vessel 섬사랑12호 --limit 10
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
프록시를 직접 확인하려면:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
BASE="${KSKILL_PROXY_BASE_URL:-https://k-skill-proxy.nomadamas.org}"
|
|
32
|
+
curl -fsS --get "$BASE/v1/komsa/ferry/schedules" \
|
|
33
|
+
--data-urlencode "date=20260824" \
|
|
34
|
+
--data-urlencode "vessel=섬사랑12호" \
|
|
35
|
+
--data-urlencode "limit=10"
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
입력은 날짜(`YYYYMMDD` 또는 `YYYY-MM-DD`), 선박명, 항로명, 기항지명, 페이지와 결과 수를 사용한다. 공식 MTIS 조회 파라미터는 명칭 필터이며, 매핑되지 않은 코드 필터는 `400`이다. 응답의 `items`는 공식 원문 필드를 보존하며, 일정 응답에는 출항일자·시각·출발지·도착지·항로·운항상태가 포함될 수 있다.
|
|
39
|
+
|
|
40
|
+
## Done when
|
|
41
|
+
|
|
42
|
+
- 공식 MTIS route를 통해 선택한 dataset을 조회했다.
|
|
43
|
+
- 결과에 조회 dataset, 페이지, 결과 수와 공식 upstream 출처를 함께 표시했다.
|
|
44
|
+
- 데이터가 5분 주기로 갱신될 수 있음을 밝히고, 운항정보를 예매 가능 좌석이나 결제 결과로 해석하지 않았다.
|
|
45
|
+
|
|
46
|
+
## Failure modes
|
|
47
|
+
|
|
48
|
+
- `400 bad_request`: 허용되지 않은 dataset, 매핑되지 않은 필터, 잘못된 날짜, 페이지 또는 결과 수.
|
|
49
|
+
- `503 upstream_not_configured`: 프록시 운영자에게 `KOMSA_MTIS_API_KEY` 설정이 필요하다.
|
|
50
|
+
- `502 upstream_error` / `502 upstream_invalid_response`: MTIS 인증 오류, quota 초과, upstream 장애 또는 응답 형식 변경.
|
|
51
|
+
- `504 upstream_timeout`: 공식 API가 시간 내 응답하지 않음.
|
|
52
|
+
- `total_count = 0`: 날짜·항로·선박 조건에 맞는 결과 없음.
|
|
53
|
+
|
|
54
|
+
MTIS OpenAPI 이용신청/키 발급은 공식 포털 회원가입·로그인 후 진행한다. 키를 채팅, 저장소, GitHub Actions에 넣지 않는다.
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"""Query KOMSA MTIS ferry information through k-skill-proxy."""
|
|
2
|
+
|
|
3
|
+
import argparse
|
|
4
|
+
import json
|
|
5
|
+
import os
|
|
6
|
+
import sys
|
|
7
|
+
import urllib.error
|
|
8
|
+
import urllib.parse
|
|
9
|
+
import urllib.request
|
|
10
|
+
|
|
11
|
+
DEFAULT_PROXY = "https://k-skill-proxy.nomadamas.org"
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def proxy_base_url(value=None, env=None):
|
|
15
|
+
env = os.environ if env is None else env
|
|
16
|
+
candidate = (value or env.get("KSKILL_PROXY_BASE_URL") or DEFAULT_PROXY).strip()
|
|
17
|
+
if candidate.casefold() in {"off", "false", "0", "none"}:
|
|
18
|
+
raise ValueError("KSKILL_PROXY_BASE_URL is disabled.")
|
|
19
|
+
return candidate.rstrip("/")
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def query(dataset, params, *, base_url=None, read_json=None):
|
|
23
|
+
url = f"{proxy_base_url(base_url)}/v1/komsa/ferry/{urllib.parse.quote(dataset, safe='')}"
|
|
24
|
+
query_string = urllib.parse.urlencode({k: v for k, v in params.items() if v is not None})
|
|
25
|
+
request = urllib.request.Request(
|
|
26
|
+
f"{url}?{query_string}",
|
|
27
|
+
headers={"Accept": "application/json", "User-Agent": "k-skill-komsa-ferry-info/1.0"},
|
|
28
|
+
method="GET",
|
|
29
|
+
)
|
|
30
|
+
if read_json:
|
|
31
|
+
return read_json(request)
|
|
32
|
+
try:
|
|
33
|
+
with urllib.request.urlopen(request, timeout=30) as response:
|
|
34
|
+
return json.loads(response.read().decode("utf-8"))
|
|
35
|
+
except urllib.error.HTTPError as error:
|
|
36
|
+
body = error.read().decode("utf-8", errors="replace")
|
|
37
|
+
try:
|
|
38
|
+
payload = json.loads(body)
|
|
39
|
+
except json.JSONDecodeError:
|
|
40
|
+
payload = {"error": f"HTTP {error.code}", "message": body}
|
|
41
|
+
raise RuntimeError(json.dumps(payload, ensure_ascii=False)) from error
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def parser():
|
|
45
|
+
result = argparse.ArgumentParser(description="KOMSA MTIS 연안여객선 정보 조회")
|
|
46
|
+
result.add_argument("dataset", choices=["schedules", "vessels", "ports", "license-routes", "operation-routes", "status"])
|
|
47
|
+
result.add_argument("--date")
|
|
48
|
+
result.add_argument("--vessel")
|
|
49
|
+
result.add_argument("--route")
|
|
50
|
+
result.add_argument("--port")
|
|
51
|
+
result.add_argument("--page", default="1")
|
|
52
|
+
result.add_argument("--limit", default="10")
|
|
53
|
+
result.add_argument("--proxy-base-url")
|
|
54
|
+
return result
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def main(argv=None):
|
|
58
|
+
args = parser().parse_args(argv)
|
|
59
|
+
params = {
|
|
60
|
+
"date": args.date,
|
|
61
|
+
"vessel": args.vessel,
|
|
62
|
+
"route": args.route,
|
|
63
|
+
"port": args.port,
|
|
64
|
+
"page": args.page,
|
|
65
|
+
"limit": args.limit,
|
|
66
|
+
}
|
|
67
|
+
try:
|
|
68
|
+
print(json.dumps(query(args.dataset, params, base_url=args.proxy_base_url), ensure_ascii=False, indent=2))
|
|
69
|
+
return 0
|
|
70
|
+
except (ValueError, RuntimeError) as error:
|
|
71
|
+
print(json.dumps({"error": str(error)}, ensure_ascii=False), file=sys.stderr)
|
|
72
|
+
return 1
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
if __name__ == "__main__":
|
|
76
|
+
raise SystemExit(main())
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "komsa-ferry-info",
|
|
3
|
+
"description": "한국해양교통안전공단 KOMSA MTIS 공식 API로 연안여객선 운항 일정과 선박·항로 정보를 조회한다.",
|
|
4
|
+
"profiles": ["proxy", "lookup"],
|
|
5
|
+
"frontmatter": "name: komsa-ferry-info\ndescription: 한국해양교통안전공단 KOMSA MTIS 공식 API로 연안여객선 운항 일정과 선박·항로 정보를 조회한다.\nlicense: MIT\nmetadata:\n category: transport\n locale: ko-KR\n phase: v1"
|
|
6
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Unified Railway Timetable Lookup
|
|
2
|
+
|
|
3
|
+
## What this skill does
|
|
4
|
+
|
|
5
|
+
`railway-timetable`은 코레일 공식 통합 시간표에서 KTX 계열 고속철도 운행 정보를 조회한다.
|
|
6
|
+
|
|
7
|
+
- KTX: 한국철도공사 공식 공개 XLSX 통합 계획 시간표
|
|
8
|
+
|
|
9
|
+
모든 경로는 조회 전용이다. 로그인·credential, 예약·예약대기·좌석 선점·결제·취소·자동 재조회는 실행하지 않는다.
|
|
10
|
+
|
|
11
|
+
## Commands
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npx -y @nomadamas/k-skill@0 exec railway-timetable scripts/railway_timetable.py -- \
|
|
15
|
+
search --dep 서울 --arr 부산 --date 20260904 \
|
|
16
|
+
--time 0600 --time-limit 1200 --limit 5
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npx -y @nomadamas/k-skill@0 exec railway-timetable scripts/railway_timetable.py -- source
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Output
|
|
24
|
+
|
|
25
|
+
- `count`, `trains[]`, `date`
|
|
26
|
+
- 각 열차의 `operator`, `train_no`, `train_type`, `dep`, `arr`, `dep_time`, `arr_time`
|
|
27
|
+
- 공식 `source`와 예약 진입 URL
|
|
28
|
+
|
|
29
|
+
결과는 코레일 통합 공개 계획 시간표이며 실제 운휴·지연, 예약 성공, 좌석 선점을 보장하지 않는다.
|
|
30
|
+
|
|
31
|
+
## Sources and failure modes
|
|
32
|
+
|
|
33
|
+
- 코레일: 공개 게시판의 XLSX를 읽는다. 게시판·파일 장애, 적용 시간표 없음, 형식 변경, 구간 결과 없음이 발생할 수 있다.
|
|
34
|
+
- CAPTCHA·인증·접근 차단은 우회하지 않고 코레일 공식 페이지를 안내한다.
|
|
35
|
+
|
|
36
|
+
## Hard boundaries
|
|
37
|
+
|
|
38
|
+
- 회원 로그인·credential 요청 금지
|
|
39
|
+
- 예약·결제·취소·정확한 좌석 선택·자동 polling 금지
|
|
40
|
+
- 내부 모바일 API, anti-bot, CAPTCHA, 인증 통제 우회 금지
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# DISCLAIMER — `railway-timetable`
|
|
2
|
+
|
|
3
|
+
이 스킬은 한국철도공사·코레일 또는 다른 철도 운영사의 공식 기능이나 공식 지원 도구가 아니며, 제휴·후원·승인·인증 또는 협업한 사실이 없습니다. 명칭과 상표는 조회 대상 서비스를 식별하기 위해서만 사용합니다.
|
|
4
|
+
|
|
5
|
+
공개 정보의 개인적 조회는 비조직적 용도로 제한한다. 체계적·대량 수집, 데이터베이스 구축, 접근통제·차단 우회, 서비스 운영을 방해하는 행위에 사용하지 않는다.
|
|
6
|
+
|
|
7
|
+
관련 기준으로 대법원 2005도1637 및 2021도1533 판결, 정보통신망법 제48조와 저작권법 제93조를 참고한다. 이 문서는 개별 사실관계에 대한 법률 자문이나 위법성 판단이 아니다.
|
package/skills/{ktx-booking/scripts/ktx_booking.py → railway-timetable/scripts/ktx_backend.py}
RENAMED
|
File without changes
|
|
@@ -120,8 +120,6 @@ def parse_timetable_rows(
|
|
|
120
120
|
if section.type_index >= 0
|
|
121
121
|
else "KTX"
|
|
122
122
|
)
|
|
123
|
-
if "KTX" not in train_type:
|
|
124
|
-
continue
|
|
125
123
|
if section.note_index >= 0 and not runs_on_date(row[section.note_index], requested_date):
|
|
126
124
|
continue
|
|
127
125
|
dep_time = normalize_time(row[section.dep_index])
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
#!/usr/bin/env -S uv run --locked --script
|
|
2
|
+
# /// script
|
|
3
|
+
# requires-python = ">=3.11"
|
|
4
|
+
# dependencies = ["openpyxl==3.1.5"]
|
|
5
|
+
# ///
|
|
6
|
+
"""Read-only Korail integrated railway timetable lookup."""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import argparse
|
|
11
|
+
import json
|
|
12
|
+
import sys
|
|
13
|
+
from typing import Any
|
|
14
|
+
|
|
15
|
+
import ktx_backend
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def source_info() -> dict[str, Any]:
|
|
19
|
+
return {
|
|
20
|
+
"mode": "plan",
|
|
21
|
+
"transport": "Korail integrated timetable",
|
|
22
|
+
"operator": "한국철도공사",
|
|
23
|
+
"endpoint": ktx_backend.BOARD_URL,
|
|
24
|
+
"authentication": "none",
|
|
25
|
+
"mutation": "none; timetable lookup only",
|
|
26
|
+
"booking_url": ktx_backend.BOOKING_URL,
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def search(
|
|
31
|
+
*,
|
|
32
|
+
dep: str,
|
|
33
|
+
arr: str,
|
|
34
|
+
date: str,
|
|
35
|
+
earliest: str,
|
|
36
|
+
latest: str,
|
|
37
|
+
limit: int,
|
|
38
|
+
) -> dict[str, Any]:
|
|
39
|
+
result = ktx_backend.search_public_timetable(
|
|
40
|
+
dep=dep,
|
|
41
|
+
arr=arr,
|
|
42
|
+
date=date,
|
|
43
|
+
earliest=earliest,
|
|
44
|
+
latest=latest,
|
|
45
|
+
limit=limit,
|
|
46
|
+
)
|
|
47
|
+
return {
|
|
48
|
+
**result,
|
|
49
|
+
"schedule_note": "코레일 통합 공개 운행계획 기준이며 실시간 운휴·지연·잔여석 정보가 아닙니다.",
|
|
50
|
+
"source": {**result["source"], "transport": "Korail integrated timetable"},
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def build_parser() -> argparse.ArgumentParser:
|
|
55
|
+
parser = argparse.ArgumentParser(
|
|
56
|
+
description="Korail integrated read-only railway timetable lookup",
|
|
57
|
+
)
|
|
58
|
+
commands = parser.add_subparsers(dest="command", required=True)
|
|
59
|
+
search_parser = commands.add_parser("search", help="search railway timetables")
|
|
60
|
+
search_parser.add_argument("--dep", required=True)
|
|
61
|
+
search_parser.add_argument("--arr", required=True)
|
|
62
|
+
search_parser.add_argument("--date", required=True, help="YYYYMMDD")
|
|
63
|
+
search_parser.add_argument("--time", default="0000", help="earliest departure, HHMM")
|
|
64
|
+
search_parser.add_argument("--time-limit", default="2359", help="latest departure, HHMM")
|
|
65
|
+
search_parser.add_argument("--limit", type=int, default=10)
|
|
66
|
+
commands.add_parser("source", help="show read-only timetable sources")
|
|
67
|
+
return parser
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def main(argv: list[str] | None = None) -> int:
|
|
71
|
+
parser = build_parser()
|
|
72
|
+
args = parser.parse_args(argv)
|
|
73
|
+
try:
|
|
74
|
+
if args.command == "source":
|
|
75
|
+
print(json.dumps(source_info(), ensure_ascii=False, indent=2))
|
|
76
|
+
return 0
|
|
77
|
+
if args.limit < 1 or args.limit > 50:
|
|
78
|
+
raise ValueError("--limit must be between 1 and 50")
|
|
79
|
+
result = search(
|
|
80
|
+
dep=args.dep,
|
|
81
|
+
arr=args.arr,
|
|
82
|
+
date=args.date,
|
|
83
|
+
earliest=args.time,
|
|
84
|
+
latest=args.time_limit,
|
|
85
|
+
limit=args.limit,
|
|
86
|
+
)
|
|
87
|
+
print(json.dumps(result, ensure_ascii=False, indent=2))
|
|
88
|
+
return 0
|
|
89
|
+
except (RuntimeError, ValueError) as exc:
|
|
90
|
+
parser.error(str(exc))
|
|
91
|
+
return 2
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
if __name__ == "__main__":
|
|
95
|
+
sys.exit(main())
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
version = 1
|
|
2
|
+
revision = 1
|
|
3
|
+
requires-python = ">=3.11"
|
|
4
|
+
|
|
5
|
+
[manifest]
|
|
6
|
+
requirements = [{ name = "openpyxl", specifier = "==3.1.5" }]
|
|
7
|
+
|
|
8
|
+
[[package]]
|
|
9
|
+
name = "et-xmlfile"
|
|
10
|
+
version = "2.0.0"
|
|
11
|
+
source = { registry = "https://pypi.org/simple" }
|
|
12
|
+
sdist = { url = "https://files.pythonhosted.org/packages/d3/38/af70d7ab1ae9d4da450eeec1fa3918940a5fafb9055e934af8d6eb0c2313/et_xmlfile-2.0.0.tar.gz", hash = "sha256:dab3f4764309081ce75662649be815c4c9081e88f0837825f90fd28317d4da54", size = 17234 }
|
|
13
|
+
wheels = [
|
|
14
|
+
{ url = "https://files.pythonhosted.org/packages/c1/8b/5fe2cc11fee489817272089c4203e679c63b570a5aaeb18d852ae3cbba6a/et_xmlfile-2.0.0-py3-none-any.whl", hash = "sha256:7a91720bc756843502c3b7504c77b8fe44217c85c537d85037f0f536151b2caa", size = 18059 },
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
[[package]]
|
|
18
|
+
name = "openpyxl"
|
|
19
|
+
version = "3.1.5"
|
|
20
|
+
source = { registry = "https://pypi.org/simple" }
|
|
21
|
+
dependencies = [
|
|
22
|
+
{ name = "et-xmlfile" },
|
|
23
|
+
]
|
|
24
|
+
sdist = { url = "https://files.pythonhosted.org/packages/3d/f9/88d94a75de065ea32619465d2f77b29a0469500e99012523b91cc4141cd1/openpyxl-3.1.5.tar.gz", hash = "sha256:cf0e3cf56142039133628b5acffe8ef0c12bc902d2aadd3e0fe5878dc08d1050", size = 186464 }
|
|
25
|
+
wheels = [
|
|
26
|
+
{ url = "https://files.pythonhosted.org/packages/c0/da/977ded879c29cbd04de313843e76868e6e13408a94ed6b987245dc7c8506/openpyxl-3.1.5-py2.py3-none-any.whl", hash = "sha256:5282c12b107bffeef825f4617dc029afaf41d0ea60823bbb665ef3079dc79de2", size = 250910 },
|
|
27
|
+
]
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "railway-timetable",
|
|
3
|
+
"description": "Read-only Korail integrated railway timetable lookup covering KTX-family trains. No reservation, payment, cancellation, or seat holding.",
|
|
4
|
+
"profiles": [
|
|
5
|
+
"lookup"
|
|
6
|
+
],
|
|
7
|
+
"frontmatter": "name: railway-timetable\ndescription: Read-only Korail integrated railway timetable lookup covering KTX-family trains. No reservation, payment, cancellation, or seat holding.\nlicense: MIT\nmetadata:\n category: travel\n locale: ko-KR\n phase: v1"
|
|
8
|
+
}
|
|
@@ -28,9 +28,26 @@
|
|
|
28
28
|
|
|
29
29
|
## Prerequisites
|
|
30
30
|
|
|
31
|
-
없음. 사용자는 별도 API key를 준비할 필요가 없다. upstream key는 proxy 서버에서만
|
|
31
|
+
없음. 사용자는 별도 API key를 준비할 필요가 없다. 개별 조회의 upstream key는 proxy 서버에서만 주입하며, 전국 일일 보고는 아래 공식 RTMS CSV를 직접 사용한다.
|
|
32
32
|
|
|
33
|
-
##
|
|
33
|
+
## 전국 일일 보고 — 공식 RTMS CSV 직접 조회
|
|
34
|
+
|
|
35
|
+
proxy나 ServiceKey 없이 국토교통부 실거래가 자료제공 화면의 실제 CSV 응답을 집계한다.
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
npx -y @nomadamas/k-skill@0 exec real-estate-search scripts/nationwide_daily_report.py -- --as-of YYYY-MM-DD
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
`--as-of`를 생략하면 KST 오늘을 사용한다. 공식 시·도/시·군·구 목록을 조회한 뒤 아파트·오피스텔·연립다세대·단독다가구의 매매·전월세 8개 조합을 전국 일괄 CSV로 실행한다. 현재 월이 0건이면 직전 월을 한 번 확인한다.
|
|
42
|
+
|
|
43
|
+
- `success`: CSV를 내려받아 파싱한 조합. 지역별 0건은 `empty`로 집계한다.
|
|
44
|
+
- `empty`: 현재 월과 직전 월의 공식 건수가 모두 0인 조합.
|
|
45
|
+
- `failure`: 네트워크, HTTP, 응답 크기, JSON/CSV 계약 또는 건수 불일치 오류.
|
|
46
|
+
- `unexecuted`: 실행 결과가 없는 조합. 실패나 빈 결과를 이 상태로 바꾸지 않는다.
|
|
47
|
+
|
|
48
|
+
한 조합이라도 실패하면 보고서는 성공/빈 결과/실패 범위를 모두 출력하고 종료코드 1을 반환한다. 원문 근거는 실제로 접속한 `https://rt.molit.go.kr/pt/xls/xls.do`로 고정한다.
|
|
49
|
+
|
|
50
|
+
## 개별 조회 기본 경로
|
|
34
51
|
|
|
35
52
|
추가 client API 레이어는 불필요하다. 그냥 프록시 서버에 HTTP 요청만 넣으면 된다.
|
|
36
53
|
|
|
@@ -156,17 +173,20 @@ curl -fsS --get 'https://k-skill-proxy.nomadamas.org/v1/real-estate/officetel/re
|
|
|
156
173
|
- 프록시 서버에 `DATA_GO_KR_API_KEY` 가 없으면 503 응답
|
|
157
174
|
- upstream MOLIT API 오류면 502 + `molit_api_XXX` 에러 코드
|
|
158
175
|
- 해당 지역/기간에 데이터가 없으면 빈 `items` 배열 반환
|
|
176
|
+
- 전국 일일 보고의 공식 RTMS 응답이 실패하거나 계약과 다르면 해당 조합을 `failure`로 유지하고 누락 수치나 더미 데이터를 만들지 않는다.
|
|
159
177
|
|
|
160
178
|
## Done when
|
|
161
179
|
|
|
162
180
|
- 요청 자산 타입에 맞는 endpoint를 선택했다.
|
|
163
181
|
- 필요한 경우 `region-code` 로 지역코드를 먼저 확인했다.
|
|
164
182
|
- 실거래가/전월세 결과를 조회하고 요약했다.
|
|
183
|
+
- 전국 일일 보고 요청이면 공식 RTMS CSV helper를 실행하고 success/empty/failure/unexecuted를 구분했다.
|
|
165
184
|
- 원본 데이터 출처(국토교통부 실거래가 신고)를 함께 남겼다.
|
|
166
185
|
|
|
167
186
|
## Notes
|
|
168
187
|
|
|
169
188
|
- 원본 참고: `https://github.com/tae0y/real-estate-mcp/tree/main`
|
|
170
189
|
- 공식 데이터 출처: 공공데이터포털 (`https://www.data.go.kr`)
|
|
190
|
+
- 공식 RTMS CSV 자료제공: `https://rt.molit.go.kr/pt/xls/xls.do`
|
|
171
191
|
- 가격 단위: `price_10k`, `deposit_10k` = 만원 단위 (예: 245000 = 24억 5천만원)
|
|
172
192
|
- 취소된 거래는 서버에서 자동 필터링된다.
|