본문 바로가기

Study Information Technology

실시간 웹 애플리케이션 구축 Django를 사용한 공공 API로부터의 라이브 데이터 표시

728x90
반응형

실시간 웹 애플리케이션 구축: Django를 사용한 공공 API로부터의 라이브 데이터 표시

Overview

실시간 웹 애플리케이션을 구축하는 것은 사용자에게 최신 정보를 즉시 제공하는 데 매우 중요합니다. Django를 사용하여 공공 API에서 실시간으로 데이터를 받아와 웹 애플리케이션에서 표시하는 것은 복잡하지만 매력적인 작업입니다. 이 설명에서는 Django와 다양한 기술을 활용하여 실시간 웹 애플리케이션을 구축하는 방법을 자세히 다루겠습니다. 예시로, 특정 공공 API로부터 날씨 정보를 실시간으로 받아와 사용자에게 표시하는 웹 애플리케이션을 만드는 방법을 살펴보겠습니다.

1. 프로젝트 설정 및 기본 구성

1.1 Django 프로젝트 및 앱 생성

  1. Django 설치 및 프로젝트 생성
    Django를 설치하고 새로운 프로젝트를 생성합니다.

    pip install django
    django-admin startproject liveweather
    cd liveweather
  2. 새 앱 생성
    실시간 날씨 정보를 처리할 앱을 생성합니다.

    python manage.py startapp weather
  3. 앱 등록
    liveweather/settings.py 파일을 열어 INSTALLED_APPS 리스트에 새 앱을 추가합니다.

    INSTALLED_APPS = [
    ...
    'weather',
    ]

1.2 Django 설정

Django 프로젝트의 기본 설정을 완료합니다. 데이터베이스 설정, 미들웨어, 정적 파일 설정 등 필요한 구성을 마칩니다.

2. 공공 API와의 통합

2.1 공공 API 선택 및 요청

이번 예시에서는 OpenWeatherMap API를 사용하여 날씨 정보를 실시간으로 가져옵니다. OpenWeatherMap API의 무료 플랜을 사용하면 일정량의 요청을 무료로 할 수 있습니다.

  1. API 키 발급
    OpenWeatherMap의 공식 웹사이트에서 API 키를 발급받습니다.
    OpenWeatherMap

  2. API 요청 구현
    Django 앱에서 API 요청을 보내기 위해 requests 라이브러리를 사용합니다.

    pip install requests
  3. 날씨 정보 가져오기
    weather/views.py 파일에 API 요청과 응답 처리 로직을 작성합니다.

    import requests
    from django.shortcuts import render
    from django.http import JsonResponse
    

def get_weather_data(request):
api_key = 'YOUR_API_KEY'
city = 'Seoul'
url = f'http://api.openweathermap.org/data/2.5/weather?q={city}&appid={api_key}&units=metric'
response = requests.get(url)
data = response.json()

weather_data = {
'city': data['name'],
'temperature': data['main']['temp'],
'description': data['weather'][0]['description'],
}
return JsonResponse(weather_data)


### 3. 실시간 데이터 업데이트

실시간으로 데이터를 업데이트하기 위해 웹소켓을 사용합니다. Django에서는 `channels` 라이브러리를 사용하여 웹소켓을 구현할 수 있습니다.

#### 3.1 Django Channels 설치 및 설정

1. **Django Channels 설치**
```bash
pip install channels
  1. Channels 설정
    liveweather/settings.py 파일을 수정하여 Channels를 설정합니다.
    INSTALLED_APPS = [
    ...
    'channels',
    ]
    

ASGI_APPLICATION = 'liveweather.asgi.application'


`liveweather/asgi.py` 파일을 생성하고 다음과 같이 설정합니다.
```python
import os
from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.auth import AuthMiddlewareStack
from weather import routing

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'liveweather.settings')

application = ProtocolTypeRouter({
"http": get_asgi_application(),
"websocket": AuthMiddlewareStack(
URLRouter(
routing.websocket_urlpatterns
)
),
})

3.2 웹소켓 설정

  1. 웹소켓 라우팅 및 소비자 구현
    weather/routing.py 파일을 생성하고 웹소켓 라우팅을 설정합니다.
    from django.urls import re_path
    from . import consumers
    

websocket_urlpatterns = [
re_path(r'ws/weather/$', consumers.WeatherConsumer.as_asgi()),
]


2. **웹소켓 소비자 구현**
`weather/consumers.py` 파일을 생성하고 웹소켓 소비자를 구현합니다.
```python
import json
from channels.generic.websocket import AsyncWebsocketConsumer

class WeatherConsumer(AsyncWebsocketConsumer):
async def connect(self):
await self.accept()
await self.send_weather_data()

async def disconnect(self, close_code):
pass

async def send_weather_data(self):
import requests
api_key = 'YOUR_API_KEY'
city = 'Seoul'
url = f'http://api.openweathermap.org/data/2.5/weather?q={city}&appid={api_key}&units=metric'
response = requests.get(url)
data = response.json()

weather_data = {
'city': data['name'],
'temperature': data['main']['temp'],
'description': data['weather'][0]['description'],
}
await self.send(text_data=json.dumps(weather_data))

4. 클라이언트 측 구현

4.1 HTML 및 JavaScript 설정

  1. 템플릿 작성
    weather/templates/weather/index.html 파일을 생성하고 HTML 템플릿을 작성합니다.

    <!DOCTYPE html>
    <html>
    <head>
     <title>Live Weather</title>
    </head>
    <body>
     <h1>Live Weather</h1>
     <div id="weather"></div>
    
     <script>
       const weatherSocket = new WebSocket(
         'ws://' + window.location.host + '/ws/weather/'
         );
    
       weatherSocket.onmessage = function(e) {
         const data = JSON.parse(e.data);
         document.getElementById('weather').innerHTML =
           `City: ${data.city} <br> Temperature: ${data.temperature}°C <br> Description: ${data.description}`;
       };
    
       weatherSocket.onclose = function(e) {
         console.error('Weather socket closed unexpectedly');
       };
     </script>
    </body>
    </html>
  2. 뷰 설정
    weather/views.py 파일에 뷰를 추가하여 HTML 페이지를 렌더링합니다.

    from django.shortcuts import render
    

def index(request):
return render(request, 'weather/index.html')


3. **URL 설정**
`weather/urls.py` 파일을 생성하고 URL 패턴을 설정합니다.
```python
from django.urls import path
from . import views

urlpatterns = [
path('', views.index, name='index'),
]

그리고 liveweather/urls.py 파일에서 앱의 URL을 포함시킵니다.

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
path('admin/', admin.site.urls),
path('', include('weather.urls')),
]

5. 에러 처리 및 디버깅

5.1 공통 에러 및 해결 방법

  1. 403 Forbidden 에러
  • 문제: API 요청이 거부되거나 웹소켓 연결이 실패하는 경우.
  • 해결: API 키가 유효한지 확인하고, Django Channels 설정이 올바른지 검토합니다. 또한, API의 호출 제한을 초과하지 않았는지 확인합니다.
  1. 400 Bad Request 에러
  • 문제: 잘못된 요청 형식으로 인해 발생합니다.
  • 해결: 요청 URL과 파라미터가 올바르게 설정되었는지 확인합니다. 특히, API 문서에서 요구하는 필수 파라미터를 빠트리지 않았는지 점검합니다.
  1. WebSocket connection failed
  • 문제: 웹소켓 연결 실패.
  • 해결: 웹소켓 서버가 정상적으로 실행되고 있는지 확인하고, 웹소켓 URL이 올바르게 설정되었는지 검토합니다.

참고문서

728x90
반응형