[python] Tornado를 사용한 실시간 주식 시세 알림 구현

주식 시장은 매우 동적이고 실시간으로 변화하는 정보를 제공합니다. 이러한 시장 정보를 실시간으로 받아와 사용자에게 알림을 제공하는 웹 앱을 구현해보겠습니다. 이를 위해 Python의 Tornado 웹 프레임워크를 사용하여 실시간 데이터를 처리하고, WebSocket을 통해 클라이언트와 실시간으로 통신할 것입니다.

1. Tornado 설치 및 프로젝트 초기화

먼저 Tornado를 설치합니다. 다음 명령어를 사용하여 Tornado를 설치할 수 있습니다.

pip install tornado

다음으로 프로젝트를 위한 디렉토리를 만들고, 초기화합니다.

mkdir stock_alert
cd stock_alert
touch main.py
touch stock_handler.py

2. Tornado를 이용한 웹 앱 구현

main.py 파일에 다음과 같이 코드를 작성합니다.

import tornado.ioloop
import tornado.web
import tornado.websocket
from stock_handler import StockHandler

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.render("index.html")

def make_app():
    return tornado.web.Application([
        (r"/", MainHandler),
        (r"/websocket", StockHandler),
    ])

if __name__ == "__main__":
    app = make_app()
    app.listen(8888)
    tornado.ioloop.IOLoop.current().start()

위 코드에서는 MainHandler를 정의하여 “/” 경로로 접근했을 때 index.html 페이지를 렌더링하도록 합니다. StockHandler는 WebSocket 통신을 위한 핸들러로 “/websocket” 경로에 매핑됩니다.

3. 주식 데이터 처리 클래스 생성

stock_handler.py 파일을 열고 다음과 같이 코드를 작성합니다.

import tornadoredis
import json

class StockHandler(tornado.websocket.WebSocketHandler):
    listeners = set()

    def open(self):
        self.listeners.add(self)

    def on_close(self):
        self.listeners.remove(self)

    @classmethod
    def emit(cls, data):
        for listener in cls.listeners:
            listener.write_message(json.dumps(data))

위 코드에서는 StockHandler 클래스를 정의했습니다. open 메서드에서 WebSocket 커넥션이 열리면 self.listeners에 연결을 추가하고, on_close 메서드에서 연결이 닫히면 self.listeners에서 연결을 제거합니다. emit 메서드는 주식 데이터를 송출하는데, 등록된 모든 WebSocket 클라이언트에게 데이터를 보냅니다.

4. 웹 앱에 실시간 주식 시세 정보 추가

이제 index.html 파일을 만들어 웹 앱에 실시간 주식 시세 정보를 표시할 수 있도록 합니다.

<!DOCTYPE html>
<html>
<head>
    <title>Stock Alert</title>
    <script type="text/javascript">
        var ws = new WebSocket("ws://localhost:8888/websocket");

        ws.onmessage = function(event) {
            var data = JSON.parse(event.data);
            document.getElementById("stock-price").innerText = data.price;
        };
    </script>
</head>
<body>
    <h1>Stock Alert</h1>
    <p>현재 주식 가격: <span id="stock-price"></span></p>
</body>
</html>

위 코드에서 WebSocket 객체를 생성하여 서버에 연결합니다. onmessage 이벤트 핸들러에서는 서버로부터 받은 데이터를 파싱하여 주식 가격을 업데이트합니다.

5. 주식 데이터 송출기 실행

주식 데이터를 송출하는 소스 데이터를 작성합니다. 테스트를 위해 간단한 예시로 랜덤 가격을 생성하는 코드를 작성합니다.

main.py 파일 마지막에 다음 코드를 추가합니다.

import random
import time
from stock_handler import StockHandler

def send_stock_price():
    while True:
        price = random.randint(1000, 2000)
        StockHandler.emit({"price": price})
        time.sleep(1)

# ...

if __name__ == "__main__":
    app = make_app()
    app.listen(8888)
    tornado.ioloop.IOLoop.current().start()

    send_stock_price()

위 코드에서 send_stock_price 함수는 1초마다 랜덤 가격을 생성하고, StockHandler.emit을 사용하여 주식 가격을 송출합니다.

6. 웹 앱 실행

웹 앱을 실행하기 위해 터미널에서 다음 명령어를 실행합니다.

python main.py

웹 브라우저에서 http://localhost:8888에 접속하면 실시간으로 업데이트되는 주식 가격을 확인할 수 있습니다.

결론

이번 포스트에서는 Tornado를 사용하여 실시간 주식 시세 알림을 구현하는 방법에 대해 알아보았습니다. Tornado의 WebSocket 기능을 활용하여 클라이언트와 서버 간 실시간 통신을 구현함으로써 동적인 데이터를 실시간으로 업데이트할 수 있는 웹 앱을 만들 수 있습니다.


참고 문서