Skip to content

Latest commit

ย 

History

History
384 lines (274 loc) ยท 15.5 KB

datagokr.md

File metadata and controls

384 lines (274 loc) ยท 15.5 KB

data.go.kr KMA ์ง€์›

kma.KmaClient๋Š” ์‚ฌ์šฉ๋Ÿ‰์ด ๋†’์€ ๋‹จ๊ธฐ์˜ˆ๋ณด ์„œ๋น„์Šค๋ฅผ ํƒ€์ž…ํ™”๋œ ๋ชจ๋ธ๋กœ ๊ฐ์‹ผ ํด๋ผ์ด์–ธํŠธ์ž…๋‹ˆ๋‹ค. apis.data.go.kr/1360000์˜ ๋‹ค๋ฅธ KMA ๊ณต๊ณต๋ฐ์ดํ„ฐ ์„œ๋น„์Šค๋Š” DataGoKrClient๋กœ ๋ฒ”์šฉ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

๊ณต์‹ ํ™•์ธ ์ถœ์ฒ˜:

ํƒ€์ž…ํ™” ํด๋ผ์ด์–ธํŠธ

import asyncio
from kma import KmaClient


async def main() -> None:
    async with KmaClient.from_env() as kma:
        (await kma.now(nx=60, ny=127))
        (await kma.forecast_short(nx=60, ny=127))
        (await kma.forecast(nx=60, ny=127))


asyncio.run(main())

ํƒ€์ž…ํ™” ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋‹ค๋ฃจ๋Š” endpoint:

  • VilageFcstInfoService_2.0/getUltraSrtNcst
  • VilageFcstInfoService_2.0/getUltraSrtFcst
  • VilageFcstInfoService_2.0/getVilageFcst
  • VilageFcstInfoService_2.0/getFcstVersion

๋ฒ”์šฉ ํด๋ผ์ด์–ธํŠธ

import asyncio
from kma import DataGoKrClient


async def main() -> None:
    async with DataGoKrClient.from_env() as client:
        body = (await client.request(
            "MidFcstInfoService",
            "getMidFcst",
            {"stnId": "108", "tmFc": "202605010600"},
        ))


asyncio.run(main())

ํ‘œ์ค€ response.body.items.item ๊ตฌ์กฐ๋ฅผ ์“ฐ๋Š” operation์€ items()๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

from kma import DataGoKrClient
import asyncio


async def main() -> None:
    async with DataGoKrClient.from_env() as client:
        items = (await client.items(
            "MidFcstInfoService",
            "getMidFcst",
            {"stnId": "108", "tmFc": "202605010600"},
        ))


asyncio.run(main())

metadata๊ฐ€ ํ•„์š”ํ•˜๋ฉด request_with_metadata()๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. metadata์˜ request_params์—๋Š” serviceKey ์›๋ฌธ์ด ์—†์Šต๋‹ˆ๋‹ค.

from kma import DataGoKrClient
import asyncio


async def main() -> None:
    async with DataGoKrClient.from_env() as client:
        body, metadata = (await client.request_with_metadata(
            "MidFcstInfoService",
            "getMidFcst",
            {"stnId": "108", "tmFc": "202605010600"},
        ))


asyncio.run(main())

๊ธฐ์ƒ์ฒญ API ์นดํƒˆ๋กœ๊ทธ

2026-05-07 ๊ธฐ์ค€ ๊ณต๊ณต๋ฐ์ดํ„ฐํฌํ„ธ ๊ธฐ์ƒ์ฒญ ์˜คํ”ˆ API ๊ฒ€์ƒ‰์˜ ๋ชจ๋“  ํŽ˜์ด์ง€๋ฅผ ํ™•์ธํ•ด, ์ œ๋ชฉ์ด ๊ธฐ์ƒ์ฒญ์œผ๋กœ ์‹œ์ž‘ํ•˜๋Š” ํ•ญ๋ชฉ๋งŒ KMA_DATA_GOKR_DATASETS์— ๋‹ด์•˜์Šต๋‹ˆ๋‹ค. ๊ฒ€์ƒ‰์–ด์—๋Š” ๊ฑธ๋ฆฌ์ง€๋งŒ ๊ธฐ์ƒ์ฒญ์ด ์•„๋‹Œ ๊ธฐ๊ด€์˜ ํ•ญ๋ชฉ์€ ์ œ์™ธํ•ฉ๋‹ˆ๋‹ค.

์นดํƒˆ๋กœ๊ทธ 86๊ฐœ ์ค‘ ๊ธฐ์กด data.go.kr serviceKey gateway ํ•ญ๋ชฉ์€ 38๊ฐœ์ด๋ฉฐ, ํฌํ„ธ ์ƒ์„ธ๊ธฐ๋Šฅ์—์„œ ํ™•์ธํ•œ operation 160๊ฐœ๋ฅผ ํ•จ๊ป˜ ๋ณด์กดํ•ฉ๋‹ˆ๋‹ค. APIHub๋กœ ์—ฐ๊ฒฐ๋˜๋Š” 48๊ฐœ ํ•ญ๋ชฉ์€ gateway="apihub"๋กœ ๊ตฌ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. APIHub์™€ ์ •ํ™•ํžˆ ๊ฐ™์€ {service}/{operation} ์กฐํ•ฉ์€ data.go.kr/APIHub ์ค‘๋ณต ํ™•์ธ์— ํ‘œ๋กœ ์ •๋ฆฌํ–ˆ์Šต๋‹ˆ๋‹ค.

import asyncio
from kma import KMA_DATA_GOKR_DATASETS, DataGoKrClient, api_catalog


async def main() -> None:
    async with DataGoKrClient.from_env() as client:

        print(len(KMA_DATA_GOKR_DATASETS))  # 86
        for entry in api_catalog(gateway="datagokr")[:3]:
            print(entry.dataset_name, entry.operation, entry.service_key_url)

        asos_spec = client.dataset("15059093")
        rows = (await client.dataset_items(
            "15059093",
            {
                "startDt": "20260501",
                "endDt": "20260502",
                "dataCd": "ASOS",
                "dateCd": "DAY",
            },
        ))


asyncio.run(main())

api_catalog()๋Š” dataset์„ operation ๋‹จ์œ„ row๋กœ ํŽผ์ณ dataset_name, label, gateway, service, operation, credential_param, service_key_url์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. Streamlit ๊ฐ™์€ ๋””๋ฒ„๊ทธ UI์—์„œ๋Š” label์„ ์„ ํƒ ํ•ญ๋ชฉ์œผ๋กœ ์“ฐ๊ณ , ์‚ฌ์šฉ์ž๊ฐ€ ์„ ํƒํ•œ row์˜ service_key_url์„ ์„œ๋น„์Šคํ‚ค ๋ฐœ๊ธ‰/ํ™•์ธ ๋งํฌ๋กœ ๋ณด์—ฌ์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

dataset_items()๋Š” ์„œ๋น„์Šค์™€ operation์ด ํ•˜๋‚˜๋กœ ๊ฒฐ์ •๋˜๋Š” data.go.kr gateway ํ•ญ๋ชฉ์„ ๋ฐ”๋กœ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๋Ÿฌ operation์„ ๊ฐ€์ง„ ํ•ญ๋ชฉ์€ operation=์„ ๋ช…์‹œํ•ฉ๋‹ˆ๋‹ค.

from kma import DataGoKrClient
import asyncio


async def main() -> None:
    async with DataGoKrClient.from_env() as client:
        waves = (await client.dataset_items(
            "15102239",
            {"beach_num": "1", "searchTime": "202205011600"},
            operation="getWhBuoyBeach",
        ))


asyncio.run(main())

์นดํƒˆ๋กœ๊ทธ์—๋Š” APIHub๋กœ ์—ฐ๊ฒฐ๋˜๋Š” data.go.kr ํ•ญ๋ชฉ๋„ gateway="apihub"๋กœ ๋‚จ๊ฒจ ๋‘ก๋‹ˆ๋‹ค. ์ด ํ•ญ๋ชฉ์€ serviceKey gateway๊ฐ€ ์•„๋‹ˆ๋ฏ€๋กœ dataset_items()๊ฐ€ ํ˜ธ์ถœํ•˜์ง€ ์•Š๊ณ , ApiHubClient ๋˜๋Š” ApiHubGeneratedClient๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๊ธฐ๋ณธ๊ฐ’:

  • serviceKey=<DATA_GO_KR_SERVICE_KEY> ๋˜๋Š” <DATA_GO_KR_SERVICE_KEY>
  • pageNo=1
  • numOfRows=10
  • dataType=JSON

from_env()๋Š” process env๋ฅผ ๋จผ์ € ๋ณด๊ณ , ์—†์œผ๋ฉด ํ˜„์žฌ ์ž‘์—… ๋””๋ ‰ํ„ฐ๋ฆฌ์™€ ๋ถ€๋ชจ ๋””๋ ‰ํ„ฐ๋ฆฌ์˜ .env, .env.local์„ ์ฐพ์Šต๋‹ˆ๋‹ค. ๊ฐ™์€ key๊ฐ€ ์—ฌ๋Ÿฌ ๋กœ์ปฌ ํŒŒ์ผ์— ์žˆ์œผ๋ฉด ๊ฐ€๊นŒ์šด ๋””๋ ‰ํ„ฐ๋ฆฌ ๊ฐ’์ด ์šฐ์„ ํ•˜๊ณ , ๊ฐ™์€ ๋””๋ ‰ํ„ฐ๋ฆฌ์—์„œ๋Š” .env.local์ด .env๋ณด๋‹ค ์šฐ์„ ํ•ฉ๋‹ˆ๋‹ค. ์ธ์ฆํ‚ค ๊ฐ’์— ๋ณต์‚ฌ/๋ถ™์—ฌ๋„ฃ๊ธฐ ๊ณต๋ฐฑ์ด๋‚˜ ์ค„๋ฐ”๊ฟˆ์ด ์„ž์ด๋ฉด ํด๋ผ์ด์–ธํŠธ ์ƒ์„ฑ ์‹œ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.

๊ณต๊ณต๋ฐ์ดํ„ฐํฌํ„ธ ๋ฌธ์„œ๋Š” ์„œ๋น„์Šค์— ๋”ฐ๋ผ ์ธ์ฆํ‚ค ํ•ญ๋ชฉ์„ serviceKey ๋˜๋Š” ServiceKey๋กœ ํ‘œ๊ธฐํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ๊ฐ’์€ ๊ธฐ์กด data.go.kr gateway์—์„œ ๋™์ž‘ ํ™•์ธํ•œ serviceKey์ด๋ฉฐ, ํŠน์ • ์„œ๋น„์Šค๊ฐ€ ๋Œ€๋ฌธ์ž ์ด๋ฆ„์„ ์š”๊ตฌํ•˜๋ฉด ์ƒ์„ฑ์ž์—์„œ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

client = DataGoKrClient.from_env(service_key_param="ServiceKey")

Pagination helper

data.go.kr ๊ณ„์—ด response body๊ฐ€ pageNo, numOfRows, totalCount๋ฅผ ํฌํ•จํ•˜๋ฉด ๋‹ค์Œ helper๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

from kma import latest_mid_fcst_time
from kma import DataGoKrClient
import asyncio
from kma import has_next_page, next_page_no


async def main() -> None:
    async with DataGoKrClient.from_env() as client:
        body = (await client.request("MidFcstInfoService", "getMidLandFcst", {"regId": "11B00000", "tmFc": latest_mid_fcst_time()}))
        if has_next_page(body):
            print(next_page_no(body))


asyncio.run(main())

DataGoKrClient.iter_pages()๋Š” max_pages ๋˜๋Š” max_items guard๋กœ ๋ฌดํ•œ ๋ฐ˜๋ณต์„ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค.

from kma import DataGoKrClient
import asyncio


async def main() -> None:
    async with DataGoKrClient.from_env() as client:
        async for body in (client.iter_pages(
            "MidFcstInfoService",
            "getMidLandFcst",
            {"regId": "11B00000", "tmFc": "202605010600"},
            num_of_rows=100,
            max_pages=10,
        )):
            ...


asyncio.run(main())

์ค‘๊ธฐ์˜ˆ๋ณด helper

์ค‘๊ธฐ์˜ˆ๋ณด๋Š” MidFcstInfoService ํ˜ธ์ถœ๊ณผ row parsing๊นŒ์ง€๋งŒ ์ฑ…์ž„์ง‘๋‹ˆ๋‹ค. reg_id๋Š” ๋‹จ๊ธฐ์˜ˆ๋ณด nx/ny์™€ ๋‹ค๋ฅธ KMA ์ค‘๊ธฐ์˜ˆ๋ณด ๊ถŒ์—ญ ์ฝ”๋“œ์ด๋ฉฐ, kma๋Š” ์ž„์˜ ๋งคํ•‘์„ ์ถ”์ธกํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. tm_fc๋ฅผ ์ƒ๋žตํ•˜๋ฉด 06:00/18:00 ๋ฐœํ‘œ์™€ 10๋ถ„ ์กฐํšŒ ์ง€์—ฐ์„ ๋ฐ˜์˜ํ•œ ์ตœ์‹  tmFc๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

from kma import DataGoKrClient
import asyncio


async def main() -> None:
    async with DataGoKrClient.from_env() as client:
        (await client.mid_forecast(stn_id="108", tm_fc="202605010600"))
        (await client.mid_land_forecast(reg_id="11B00000", tm_fc="202605010600"))
        (await client.mid_land_forecast(reg_id="11B00000"))  # ์ตœ์‹  ์กฐํšŒ ๊ฐ€๋Šฅ tmFc ์ž๋™ ์„ ํƒ
        (await client.mid_temperature_forecast(reg_id="11B10101", tm_fc="202605010600"))
        (await client.mid_sea_forecast(reg_id="12A20000", tm_fc="202605010600"))


asyncio.run(main())

๊ฐ row๋Š” MidForecastItem์ด๋ฉฐ operation, tm_fc, reg_id, stn_id, raw, metadata๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

์‹ค์„œ๋ฒ„ MidFcstInfoService ์‘๋‹ต row๋Š” ์š”์ฒญ์˜ tmFc๋ฅผ ์—์ฝ”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. MidForecastItem.tm_fc๋Š” ์‘๋‹ต row์— tmFc๊ฐ€ ์žˆ์œผ๋ฉด ๊ทธ ๊ฐ’์„ ์šฐ์„ ํ•˜๊ณ , ์—†๊ฑฐ๋‚˜ ๋นˆ ๋ฌธ์ž์—ด์ด๋ฉด ์š”์ฒญ์— ์‹ค์ œ๋กœ ์‚ฌ์šฉํ•œ(์ž๋™ ์„ ํƒ ํฌํ•จ) tmFc๋กœ ํด๋ฐฑํ•ด ํ•ญ์ƒ ๋ฐœํ‘œ์‹œ๊ฐ์„ ์‹๋ณ„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. raw์—๋Š” ํด๋ฐฑ ๊ฐ’์„ ์ฃผ์ž…ํ•˜์ง€ ์•Š๊ณ  ์‘๋‹ต ์›๋ณธ์„ ๊ทธ๋Œ€๋กœ ๋ณด์กดํ•ฉ๋‹ˆ๋‹ค.

์ฃผ์š” ์„œ๋น„์Šค helper

2026-05-07์— ๊ณต๊ณต๋ฐ์ดํ„ฐํฌํ„ธ ๊ธฐ์ƒ์ฒญ ์˜คํ”ˆ API ๊ฒ€์ƒ‰์—์„œ ํ™•์ธํ•œ ์ฃผ์š” data.go.kr ์„œ๋น„์Šค๋Š” ์ „์šฉ helper๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. endpoint๋ณ„ ์•ˆ์ •์ ์ธ ๋„๋ฉ”์ธ ๋ชจ๋ธ์„ ํ™•์ •ํ•˜๊ธฐ ์–ด๋ ค์šด ์„œ๋น„์Šค๋Š” DataGoKrItem์œผ๋กœ ๊ฐ์‹ธ๋ฉฐ, ๊ฐ row์˜ raw์™€ ์ธ์ฆํ‚ค๊ฐ€ ์ œ๊ฑฐ๋œ metadata๋ฅผ ๋ณด์กดํ•ฉ๋‹ˆ๋‹ค.

import asyncio
from kma import DataGoKrClient


async def main() -> None:
    async with DataGoKrClient.from_env() as client:

        daily = (await client.asos_daily_weather(
            start_dt="20260501",
            end_dt="20260502",
            stn_ids=108,
        ))
        hourly = (await client.asos_hourly_weather(
            start_dt="20260501",
            start_hh="00",
            end_dt="20260501",
            end_hh="23",
            stn_ids=108,
        ))
        warnings = (await client.weather_warning_list(
            stn_id=108,
            from_tm_fc="20260501",
            to_tm_fc="20260502",
        ))
        situation = (await client.weather_situation(stn_id=108))
        land = (await client.land_forecast_message(reg_id="11B10101"))
        sea = (await client.sea_forecast_message(reg_id="12A20100"))
        tour = (await client.tour_village_forecast(course_id=1, current_date="20260501", hour="09"))
        climate = (await client.city_tour_climate_index(city_area_id=1100000000, current_date="20260501", day=3))
        uv = (await client.uv_index(area_no="1100000000", time="2026050106"))
        air = (await client.air_diffusion_index(area_no="1100000000", time="2026050106"))
        sen = (await client.sensible_temperature_index(
            area_no="1100000000",
            time="2026050106",
            request_code="A41",
        ))
        quake = (await client.earthquake_message_list(from_tm_fc="20260501", to_tm_fc="20260502"))


asyncio.run(main())

์ง€์› ๋ฒ”์œ„:

service helper
AsosDalyInfoService/getWthrDataList asos_daily_weather()
AsosHourlyInfoService/getWthrDataList asos_hourly_weather()
WthrWrnInfoService/* weather_warning(), weather_warning_list()
VilageFcstMsgService/* forecast_message(), weather_situation(), land_forecast_message(), sea_forecast_message()
TourStnInfoService1/* tour_village_forecast(), city_tour_climate_index()
LivingWthrIdxServiceV4/* sensible_temperature_index(), uv_index(), air_diffusion_index()
EqkInfoService/* earthquake_info(), earthquake_message(), earthquake_message_list(), tsunami_message(), tsunami_message_list()

weather_warning(), forecast_message(), earthquake_info()๋Š” ๊ฐ™์€ ์„œ๋น„์Šค ์•ˆ์˜ ๋‹ค๋ฅธ operation์„ ์ง์ ‘ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋Š” ์–‡์€ helper์ž…๋‹ˆ๋‹ค. ํ‘œ์ค€ response.body.items.item ํ˜•ํƒœ๋ฅผ ๋”ฐ๋ฅด๋Š” ๊ฒฝ์šฐ raw row wrapper๋กœ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

ํ•ด์ˆ˜์š•์žฅ ๋‚ ์”จ ์กฐํšŒ helper

๊ณต๊ณต๋ฐ์ดํ„ฐํฌํ„ธ ๊ธฐ์ƒ์ฒญ_์ „๊ตญ ํ•ด์ˆ˜์š•์žฅ ๋‚ ์”จ ์กฐํšŒ์„œ๋น„์Šค (BeachInfoservice)๋Š” DataGoKrClient์˜ ์ „์šฉ helper๋กœ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

import asyncio
from kma import DataGoKrClient


async def main() -> None:
    async with DataGoKrClient.from_env() as client:

        ultra = (await client.beach_ultra_short_forecast(
            beach_num=1,
            base_date="20220622",
            base_time="1230",
        ))
        forecast = (await client.beach_forecast(beach_num=1))
        waves = (await client.beach_wave_height(beach_num=1, search_time="202205011600"))
        tides = (await client.beach_tide_info(beach_num=1, base_date="20220620"))
        sun = (await client.beach_sun_info(beach_num=1, base_date="20220501"))
        water = (await client.beach_water_temperature(beach_num=1, search_time="202205011600"))


asyncio.run(main())

์ง€์› operation:

method service/operation ๋ฐ˜ํ™˜ ๋ชจ๋ธ
beach_ultra_short_forecast() BeachInfoservice/getUltraSrtFcstBeach list[BeachForecastItem]
beach_forecast() BeachInfoservice/getVilageFcstBeach list[BeachForecastItem]
beach_wave_height() BeachInfoservice/getWhBuoyBeach list[BeachWaveHeight]
beach_tide_info() BeachInfoservice/getTideInfoBeach list[BeachTideItem]
beach_sun_info() BeachInfoservice/getSunInfoBeach list[BeachSunTime]
beach_water_temperature() BeachInfoservice/getTwBuoyBeach list[BeachWaterTemperature]

์ดˆ๋‹จ๊ธฐ์˜ˆ๋ณด์™€ ๋‹จ๊ธฐ์˜ˆ๋ณด helper๋Š” base_date์™€ base_time์„ ์ƒ๋žตํ•˜๋ฉด KST ๊ธฐ์ค€ ์ตœ์‹  ์กฐํšŒ ๊ฐ€๋Šฅ ๋ฐœํ‘œ์‹œ๊ฐ์„ ์ž๋™ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค. ๋ช…์‹œํ•  ๋•Œ๋Š” ๋‘ ๊ฐ’์„ ํ•จ๊ป˜ ์ „๋‹ฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ฃผ์˜ํ•  ์ :

  • beach_num์€ ํ•ด๋ณ€์ฝ”๋“œ์ž…๋‹ˆ๋‹ค. ์œ„๋„/๊ฒฝ๋„๋‚˜ nx/ny๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค.
  • ํŒŒ๊ณ ์™€ ์ˆ˜์˜จ ์กฐํšŒ์˜ search_time์€ YYYYMMDDHHMM์ž…๋‹ˆ๋‹ค.
  • ์ผ์ถœ์ผ๋ชฐ endpoint๋Š” upstream Swagger๊ฐ€ ๋‚ ์งœ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ Base_date๋กœ ํ‘œ๊ธฐํ•˜๋ฏ€๋กœ helper๊ฐ€ ์ด ์ด๋ฆ„์„ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • ๋ชจ๋“  ๋ชจ๋ธ์€ raw์™€ ์ธ์ฆํ‚ค๊ฐ€ ์ œ๊ฑฐ๋œ metadata๋ฅผ ๋ณด์กดํ•ฉ๋‹ˆ๋‹ค.

์‹ค์ œ ์„œ๋ฒ„ ํ…Œ์ŠคํŠธ์—์„œ๋งŒ ์“ฐ๋Š” ์ธ์ฆํ‚ค๋Š” .env.local์— ๋‘˜ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ํŒŒ์ผ์€ .gitignore์— ํฌํ•จ๋˜์–ด ์ปค๋ฐ‹๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

DATA_GO_KR_SERVICE_KEY=<data.go.kr decoded service key>
DATA_GO_KR_SERVICE_KEY=<data.go.kr decoded service key>

HTTP 200 XML ์˜ค๋ฅ˜ envelope

dataType=JSON ์š”์ฒญ์ด์–ด๋„ data.go.kr gateway๋Š” quotaยท์ธ์ฆ ์˜ค๋ฅ˜๋ฅผ HTTP 200 OpenAPI_ServiceResponse XML๋กœ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. DataGoKrClient์˜ ๋น„๋™๊ธฐ ํ˜ธ์ถœ์€ JSON parse ์‹คํŒจ ๋•Œ XML์˜ returnReasonCode/resultCode๋ฅผ ๊ณตํ†ต result-code ์ •์ฑ…์œผ๋กœ ๋ถ„๋ฅ˜ํ•ฉ๋‹ˆ๋‹ค. 03์€ ๋นˆ items/totalCount=0, 22๋Š” KmaRequestError(failure_kind="quota", retryable=False)์ด๋ฉฐ, XML์ด ์•„๋‹ˆ๊ฑฐ๋‚˜ ์ฝ”๋“œ๊ฐ€ ์—†์œผ๋ฉด KmaParseError์ž…๋‹ˆ๋‹ค.

data.go.kr ๊ฒ€์ƒ‰์—์„œ ํ™•์ธํ•œ ์˜ˆ์‹œ

๊ณต์‹ data.go.kr ํŽ˜์ด์ง€์—์„œ ํ™•์ธํ•œ KMA REST ์„œ๋น„์Šค ์˜ˆ์‹œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

service operation ์˜ˆ์‹œ ๋น„๊ณ 
VilageFcstInfoService_2.0 getUltraSrtNcst, getVilageFcst KmaClient๊ฐ€ typed ์ง€์›
MidFcstInfoService getMidFcst, getMidTa, getMidLandFcst, getMidSeaFcst generic JSON/XML envelope
WthrWrnInfoService getWthrWrnList ๊ธฐ์ƒํŠน๋ณด
AsosDalyInfoService getWthrDataList ASOS ์ผ์ž๋ฃŒ
YdstInfoService getYdstSatlitImg, getYdstObs ํ™ฉ์‚ฌ์ •๋ณด
LgtDistrbInfoService getLgtDistrb ๋‚™๋ขฐ๋ถ„ํฌ๋„
CloudSatlitInfoService getGk2acldAll ๋“ฑ ์œ„์„ฑ์ž๋ฃŒ ๊ฒฝ๋Ÿ‰ํ™”
UppInfoService ํ™œ์šฉ๊ฐ€์ด๋“œ๋ณ„ operation ๊ณ ์ธต๊ธฐ์ƒ๊ด€์ธก

์ผ๋ถ€ ์ตœ์‹  data.go.kr ํ•ญ๋ชฉ์€ ๊ธฐ์กด serviceKey gateway๊ฐ€ ์•„๋‹ˆ๋ผ APIHub๋กœ ์ด๋™ํ•˜๋Š” LINK ์œ ํ˜•์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๊ฒฝ์šฐ ApiHubClient๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์ธ์ฆํ‚ค ๊ทœ์น™

requests params=๋กœ ํ˜ธ์ถœํ•  ๋•Œ๋Š” Decoding service key๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

DataGoKrClient(service_key="decoded-key")

์ด๋ฏธ ์ธ์ฝ”๋”ฉ๋œ ํ‚ค๋ฅผ params=์— ๋„ฃ์œผ๋ฉด ๋‹ค์‹œ ์ธ์ฝ”๋”ฉ๋˜์–ด SERVICE_KEY_IS_NOT_REGISTERED_ERROR๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.