파이썬으로 OpenWeatherMap 날씨 API 다루기: 키 발급부터 예외 처리까지 실전 가이드

Prompt Architect 편집팀 · 2026-06-18 · 7분

TL;DR — 파이썬 requests로 OpenWeatherMap 날씨 API를 호출하는 전 과정을 정리했습니다. API 키 발급, 응답 파싱, 자주 만나는 401/404 오류 해결, 키 보안까지 실무 관점에서 다룹니다.

현재 위치의 기온이나 습도 같은 실시간 날씨 데이터를 코드로 가져오고 싶은 순간이 있습니다. 개인 대시보드를 만들거나, 슬랙 봇에 아침 날씨를 띄우거나, 데이터 분석 파이프라인에 외부 환경 변수를 넣을 때가 대표적입니다. 이때 가장 진입 장벽이 낮은 선택지가 바로 OpenWeatherMap API입니다. 무료 등급으로도 분당 호출이 충분하고, 파이썬 requests 라이브러리만 있으면 십수 줄로 동작하는 코드를 완성할 수 있습니다.

이 글에서는 단순히 "되는 코드"를 붙여넣는 데서 그치지 않고, 키를 안전하게 다루는 법과 초보자가 가장 자주 막히는 인증·도시명 오류를 어떻게 풀지까지 함께 정리합니다.

1. OpenWeatherMap을 선택하는 이유

날씨 API는 여러 곳에서 제공하지만, OpenWeatherMap은 다음 이유로 학습·프로토타이핑에 적합합니다.

  • 무료 등급(Free tier)에서도 현재 날씨, 5일 예보 등 핵심 기능 제공
  • 도시 이름, 좌표(위경도), 도시 ID 등 여러 방식의 조회 지원
  • JSON 응답이 직관적이라 파싱이 쉬움
  • 한국 주요 도시도 영문 도시명으로 잘 조회됨

다만 무료 등급은 호출 빈도와 데이터 갱신 주기에 제한이 있으니, 상용 서비스로 확장할 때는 유료 플랜을 검토해야 합니다.

2. API 키 발급과 활성화 대기

먼저 OpenWeatherMap 회원가입 페이지에서 계정을 만듭니다. 이메일 인증이 필요하므로 실제 사용하는 주소를 입력해야 합니다.

로그인 후 API keys 메뉴로 들어가면 기본 키가 자동으로 하나 생성되어 있습니다. 용도별로 키를 분리하고 싶다면 새 키를 추가로 발급할 수도 있습니다.

가장 중요한 주의사항 하나를 미리 짚겠습니다. 새로 발급한 키는 즉시 동작하지 않습니다. 보통 수십 분에서 최대 두 시간 정도 활성화 대기 시간이 필요합니다. 발급 직후 코드를 돌렸는데 401 Unauthorized가 뜬다면, 키가 틀린 게 아니라 아직 활성화되지 않았을 가능성이 큽니다. 잠시 기다렸다가 다시 시도하세요.

3. 엔드포인트와 파라미터 이해하기

현재 날씨를 조회하는 기본 엔드포인트는 다음과 같습니다.

https://api.openweathermap.org/data/2.5/weather

여기에 쿼리 파라미터를 붙여 원하는 데이터를 요청합니다. 핵심 파라미터는 세 가지입니다.

파라미터 설명 예시
q 조회할 도시 이름 Seoul, Busan,KR
appid 발급받은 API 키 (본인 키)
units 단위 체계 metric(섭씨), imperial(화씨)

units를 생략하면 켈빈(Kelvin) 단위로 응답이 오기 때문에, 한국 사용자라면 거의 항상 metric을 지정합니다. 또한 도시명이 여러 나라에 중복될 수 있으므로 Busan,KR처럼 국가 코드를 함께 적으면 더 정확하게 조회됩니다.

4. 단계별 파이썬 구현

이제 실제 코드를 작성합니다. 원문 예제와 동작은 같지만, 키를 환경변수로 분리하고 예외 처리를 강화한 형태로 다시 구성했습니다.

먼저 필요한 라이브러리를 설치합니다.

pip install requests

4-1. 기본 버전

import requests

def fetch_current_weather(city: str, api_key: str) -> None:
    """주어진 도시의 현재 날씨를 조회해 출력한다."""
    endpoint = "https://api.openweathermap.org/data/2.5/weather"
    query = {
        "q": city,
        "appid": api_key,
        "units": "metric",  # 섭씨 단위로 받기
        "lang": "kr",        # 날씨 설명을 한국어로 받기
    }

    res = requests.get(endpoint, params=query, timeout=5)

    if res.status_code != 200:
        print(f"요청 실패 (상태 코드: {res.status_code})")
        return

    payload = res.json()
    weather_core = payload["main"]
    sky = payload["weather"][0]["description"]

    print(f"[{city} 현재 날씨]")
    print(f"기온   : {weather_core['temp']}도")
    print(f"체감   : {weather_core['feels_like']}도")
    print(f"습도   : {weather_core['humidity']}%")
    print(f"기압   : {weather_core['pressure']} hPa")
    print(f"상태   : {sky}")


if __name__ == "__main__":
    fetch_current_weather("Seoul", "여기에_본인_키")

lang=kr 파라미터를 추가하면 "맑음", "구름 조금"처럼 날씨 설명을 한국어로 받을 수 있어 사용자 화면에 바로 노출하기 편합니다.

4-2. 키를 환경변수로 분리한 버전

API 키를 소스 코드에 그대로 적어두는 것은 가장 흔하면서도 위험한 실수입니다. 깃허브에 푸시하는 순간 키가 노출됩니다. 환경변수로 분리하는 것이 기본입니다.

import os
import requests


def fetch_current_weather(city: str) -> dict | None:
    """환경변수에서 키를 읽어 날씨 데이터를 dict로 반환한다."""
    api_key = os.environ.get("OWM_API_KEY")
    if not api_key:
        raise RuntimeError("환경변수 OWM_API_KEY가 설정되지 않았습니다.")

    endpoint = "https://api.openweathermap.org/data/2.5/weather"
    query = {"q": city, "appid": api_key, "units": "metric", "lang": "kr"}

    try:
        res = requests.get(endpoint, params=query, timeout=5)
        res.raise_for_status()  # 4xx/5xx면 예외 발생
    except requests.exceptions.HTTPError as e:
        print(f"HTTP 오류: {e}")
        return None
    except requests.exceptions.RequestException as e:
        print(f"네트워크 오류: {e}")
        return None

    return res.json()


if __name__ == "__main__":
    data = fetch_current_weather("Seoul")
    if data:
        print(f"서울 기온: {data['main']['temp']}도")

실행 전 터미널에서 키를 환경변수로 등록합니다.

# macOS / Linux
export OWM_API_KEY="발급받은_키"

# Windows (PowerShell)
$env:OWM_API_KEY="발급받은_키"

5. 응답 JSON 구조 뜯어보기

API가 돌려주는 JSON에서 우리가 자주 쓰는 부분만 추리면 다음과 같습니다.

{
  "weather": [
    { "main": "Clouds", "description": "구름조금" }
  ],
  "main": {
    "temp": 24.3,
    "feels_like": 24.1,
    "humidity": 55,
    "pressure": 1012
  },
  "wind": { "speed": 3.2 },
  "name": "Seoul"
}
  • main 객체: 기온(temp), 체감온도(feels_like), 습도(humidity), 기압(pressure)
  • weather 배열: 첫 번째 요소의 description이 사람이 읽을 날씨 설명
  • wind 객체: 풍속(speed)

weather가 객체가 아니라 배열이라는 점에 주의하세요. 그래서 payload["weather"][0]["description"]처럼 인덱스 0으로 접근해야 합니다. 이 부분에서 KeyError가 아닌 TypeError로 헷갈리는 초보자가 많습니다.

6. 자주 만나는 오류와 해결법

401 Unauthorized

가장 흔한 오류입니다. 원인은 보통 둘 중 하나입니다.

  1. 키가 아직 활성화되지 않음 — 발급 직후라면 최대 2시간 기다립니다.
  2. 키 오타 또는 따옴표 문제 — 복사 과정에서 공백이 섞이지 않았는지 확인합니다.

404 Not Found

{"cod":"404","message":"city not found"} 형태로 옵니다. 도시 이름 철자가 틀렸거나, 동일 이름의 다른 도시가 우선 매칭된 경우입니다. q=Daegu,KR처럼 국가 코드를 붙이면 해결되는 경우가 많습니다.

429 Too Many Requests

무료 등급의 호출 제한을 초과했을 때 발생합니다. 반복 호출이 필요하면 응답을 일정 시간 캐싱하거나, 호출 간격을 두세요.

7. 실무에서 빠지기 쉬운 함정

  • 타임아웃을 반드시 설정하세요. requests.get()timeout을 주지 않으면 외부 API가 응답하지 않을 때 프로그램이 무한 대기에 빠집니다.
  • 응답 키에 직접 접근하지 말고 방어적으로 파싱하세요. 오류 응답에는 main 키 자체가 없습니다. data.get("main", {})처럼 접근하거나, 상태 코드를 먼저 확인하는 습관이 안전합니다.
  • 키를 깃에 커밋하지 마세요. .env 파일과 .gitignore를 활용하고, 이미 푸시했다면 즉시 키를 폐기·재발급해야 합니다.
  • HTTPS를 쓰세요. http://도 동작하지만, 키가 평문으로 전송되지 않도록 https:// 엔드포인트를 사용하는 편이 안전합니다.

8. AI에게 물어볼 때 (프롬프트 팁)

OpenWeatherMap 같은 외부 API 연동은 ChatGPT나 Claude에게 물으면 빠르게 풀리지만, 질문을 막연하게 던지면 일반론만 돌아옵니다. 맥락·제약·원하는 출력 형태를 명확히 적는 것이 핵심입니다. Prompt Architect의 분석 기준으로 보면, 좋은 프롬프트는 역할·맥락·제약·출력 형식을 모두 담습니다.

예시 1 — 오류 디버깅

너는 파이썬 백엔드 개발자다. OpenWeatherMap weather API를 requests로 호출하는데
401 Unauthorized가 계속 발생한다. 내 코드는 [코드 붙여넣기]이고, 키는 30분 전에 발급했다.
가능한 원인을 우선순위 순으로 나열하고, 각 원인별 확인 명령어와 수정 코드를 제시해줘.

예시 2 — 기능 확장

아래 현재 날씨 조회 코드를 [코드 붙여넣기] 5일 예보 엔드포인트(/forecast)로 확장하고 싶다.
응답을 날짜별 최고/최저 기온으로 집계해 dict로 반환하는 함수로 리팩토링해줘.
타임아웃과 예외 처리는 유지하고, 변경한 부분을 주석으로 설명해줘.

예시 3 — 보안 점검

이 파이썬 스크립트에서 API 키 노출 위험과 네트워크 예외 처리 취약점을 코드 리뷰해줘.
각 지적 사항에 대해 위험도(상/중/하)와 수정 예시를 함께 제시하고,
.env 기반 키 관리로 바꾸는 최소 변경 패치를 보여줘.

이렇게 역할·현재 상태·원하는 출력을 구체적으로 지정하면, AI가 추측 대신 실행 가능한 답을 내놓습니다.


요약

OpenWeatherMap API는 파이썬 requests만으로 손쉽게 실시간 날씨를 가져올 수 있는 좋은 출발점입니다. 핵심은 (1) 키 발급 후 활성화 대기를 인지하기, (2) units=metric·lang=kr로 사용성을 높이기, (3) 키를 환경변수로 분리하고 타임아웃·예외 처리를 갖추기입니다. 401/404 같은 오류도 원인만 알면 대부분 몇 분 안에 해결됩니다. 여기에 5일 예보나 좌표 기반 조회를 더하면 실제 서비스로 확장할 수 있습니다.