๐Ÿ“ฆ๋ถ„์„ ํ”„๋กœ์ ํŠธ/๐ŸŽฎ RIOT API ๋ถ„์„ ๋ฐ ์›น์„œ๋น„์Šค ๊ฐœ๋ฐœ

๐ŸŽฎRIOT API ๋ถ„์„ ํ”„๋กœ์ ํŠธ(9) - Flask๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์›นํŽ˜์ด์ง€ ๋งŒ๋“ค๊ธฐ

๋ฐ์ดํ„ฐํŒ์Šค 2024. 9. 22. 16:39

flask๋ฅผ ํ™œ์šฉํ•ด ๋ฐฑ์•ค๋“œ ๊ฐœ๋ฐœ

from flask import Flask, request, jsonify, render_template
import mysql.connector
import requests

app = Flask(__name__)

# MySQL ์—ฐ๊ฒฐ ์„ค์ •
def get_db_connection():
    return mysql.connector.connect(
        host="localhost",
        user='root',
        password='pw',
        database='riot_game_db'
    )

# ๋ผ์ด์—‡ API URL ์„ค์ •
RIOT_API_KEY = "my_api"
RIOT_API_URL = "https://asia.api.riotgames.com"

# ๋ฉ”์ธ ํŽ˜์ด์ง€ - ์œ ์ € ๊ฒ€์ƒ‰ ํผ์„ ๋ณด์—ฌ์คŒ
@app.route('/')
def index():
    return render_template('index.html')

# ๋‹‰๋„ค์ž„ ๊ฒ€์ƒ‰ ๋ฐ ๊ฒŒ์ž„ ์ •๋ณด ์กฐํšŒ ํ•จ์ˆ˜
@app.route('/search', methods=['POST'])
def search_user():
    summoner_name = request.form.get('summoner_name')

    if not summoner_name:
        return render_template('index.html', error="๋‹‰๋„ค์ž„์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”")

    # MySQL ์—ฐ๊ฒฐ
    connection = get_db_connection()
    cursor = connection.cursor(dictionary=True)

    try:
        # 1. duplicated_GM_users ํ…Œ์ด๋ธ”์—์„œ puuid ์กฐํšŒ
        cursor.execute("SELECT puuid FROM duplicated_GM_users WHERE summoner_name = %s", (summoner_name,))
        result = cursor.fetchone()

        if result:
            puuid = result['puuid']

            # 2. ๋ผ์ด์—‡ API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ตœ๊ทผ 5ํŒ์˜ ๊ฒŒ์ž„ ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐ
            match_ids = get_recent_matches(puuid, 5)

            if not match_ids:
                return render_template('index.html', error="๊ฒŒ์ž„ ์ •๋ณด๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.")

            # 3. ๋งค์น˜๋ณ„ ์ƒ์„ธ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ค๊ธฐ
            games_info = []
            for match_id in match_ids:
                match_info = get_match_info(match_id)
                if match_info:
                    games_info.append(match_info)

            # DB ์—ฐ๊ฒฐ ํ•ด์ œ
            cursor.close()
            connection.close()

            # 4. ๊ฒฐ๊ณผ๋ฅผ HTML ํŽ˜์ด์ง€์— ์ „๋‹ฌ
            return render_template('results.html', games_info=games_info, summoner_name=summoner_name)

        else:
            cursor.close()
            connection.close()
            return render_template('index.html', error="์œ ์ €๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค")
    
    except mysql.connector.Error as err:
        cursor.close()
        connection.close()
        return render_template('index.html', error=f"MySQL ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {err}")
    except Exception as e:
        cursor.close()
        connection.close()
        return render_template('index.html', error=f"์˜ค๋ฅ˜ ๋ฐœ์ƒ: {e}")

# ์ตœ๊ทผ ๋งค์น˜ ID๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ํ•จ์ˆ˜
def get_recent_matches(puuid, count):
    url = f"{RIOT_API_URL}/lol/match/v5/matches/by-puuid/{puuid}/ids?start=0&count={count}&api_key={RIOT_API_KEY}"

    try:
        response = requests.get(url)
        response.raise_for_status()  # ์ƒํƒœ ์ฝ”๋“œ๊ฐ€ 200์ด ์•„๋‹ˆ๋ฉด ์˜ˆ์™ธ ๋ฐœ์ƒ

        if response.status_code == 200:
            return response.json()  # ๋งค์น˜ ID ๋ฆฌ์ŠคํŠธ ๋ฐ˜ํ™˜
        elif response.status_code == 404:
            print("๋งค์น˜ ID๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.")
            return []
        elif response.status_code == 429:
            print("API ์š”์ฒญ ์ œํ•œ์ด ์ดˆ๊ณผ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ž ์‹œ ํ›„ ๋‹ค์‹œ ์‹œ๋„ํ•˜์„ธ์š”.")
            return []
        else:
            print(f"์•Œ ์ˆ˜ ์—†๋Š” ์˜ค๋ฅ˜ ๋ฐœ์ƒ: ์ƒํƒœ ์ฝ”๋“œ {response.status_code}")
            return []

    except requests.exceptions.RequestException as e:
        print(f"API ์š”์ฒญ ์˜ค๋ฅ˜: {e}")
        return []

# ํŠน์ • ๋งค์น˜์˜ ๊ฒŒ์ž„ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ํ•จ์ˆ˜
def get_match_info(match_id):
    url = f"{RIOT_API_URL}/lol/match/v5/matches/{match_id}?api_key={RIOT_API_KEY}"

    try:
        response = requests.get(url)
        response.raise_for_status()  # ์ƒํƒœ ์ฝ”๋“œ๊ฐ€ 200์ด ์•„๋‹ˆ๋ฉด ์˜ˆ์™ธ ๋ฐœ์ƒ

        if response.status_code == 200:
            match_data = response.json()
            return extract_player_data(match_data)
        else:
            print(f"๋งค์น˜ ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐ ์‹คํŒจ, ์ƒํƒœ ์ฝ”๋“œ: {response.status_code}")
            return None

    except requests.exceptions.RequestException as e:
        print(f"API ์š”์ฒญ ์˜ค๋ฅ˜: {e}")
        return None

# ํ”Œ๋ ˆ์ด์–ด ์ •๋ณด ์ถ”์ถœ (๊ฒŒ์ž„ ์ •๋ณด์—์„œ ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋งŒ ๊ฐ€์ ธ์˜ค๊ธฐ)
def extract_player_data(match_data):
    for participant in match_data['info']['participants']:
        player_info = {
            'kills': participant['kills'],
            'deaths': participant['deaths'],
            'gold_earned': participant['goldEarned'],
            'wards_placed': participant['wardsPlaced'],
            'wards_bought': participant['visionWardsBoughtInGame'],
            'css': participant['totalMinionsKilled'],
            'assists': participant['assists'],
            'kda': participant['challenges']['kda'] if 'challenges' in participant else None,
            'teamPosition': participant['teamPosition']
        }
        return player_info

if __name__ == '__main__':
    app.run(debug=True)

 

์ฝ”๋“œ์— ๋Œ€ํ•œ ์„ค๋ช…์€ ์ด์ „ ๊ธ€(7)์— ๋‚˜์™€์žˆ์„ํ…Œ๋‹ˆ ํ™•์ธํ•ด์ฃผ์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค!

 

 

๊ฒ€์ƒ‰ํ•  ํŽ˜์ด์ง€ HTML ์ƒ์„ฑ

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Game Stats Search</title>
</head>
<body>
    <h1>์†Œํ™˜์‚ฌ ๋‹‰๋„ค์ž„์œผ๋กœ ๊ฒŒ์ž„ ์ •๋ณด ๊ฒ€์ƒ‰</h1>
    <form action="/search" method="post">
        <label for="summoner_name">๋‹‰๋„ค์ž„:</label>
        <input type="text" id="summoner_name" name="summoner_name" required>
        <button type="submit">๊ฒ€์ƒ‰</button>
    </form>

    {% if error %}
        <p style="color:red;">{{ error }}</p>
    {% endif %}
</body>
</html>

 

 

๊ฒ€์ƒ‰๊ฒฐ๊ณผ ํŽ˜์ด์ง€ HTML ์ƒ์„ฑ

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{{ summoner_name }}์˜ ์ตœ๊ทผ 5ํŒ ๊ฒŒ์ž„ ์ •๋ณด</title>
</head>
<body>
    <h1>{{ summoner_name }}์˜ ์ตœ๊ทผ 5ํŒ ๊ฒŒ์ž„ ์ •๋ณด</h1>
    
    {% if games_info %}
        <table border="1">
            <thead>
                <tr>
                    <th>ํ‚ฌ</th>
                    <th>๋ฐ์Šค</th>
                    <th>๊ณจ๋“œ ํš๋“</th>
                    <th>์™€๋“œ ๋ฐฐ์น˜</th>
                    <th>์™€๋“œ ๊ตฌ๋งค</th>
                    <th>CS</th>
                    <th>์–ด์‹œ์ŠคํŠธ</th>
                    <th>KDA</th>
                    <th>ํŒ€ ํฌ์ง€์…˜</th>
                </tr>
            </thead>
            <tbody>
                {% for game in games_info %}
                <tr>
                    <td>{{ game.kills }}</td>
                    <td>{{ game.deaths }}</td>
                    <td>{{ game.gold_earned }}</td>
                    <td>{{ game.wards_placed }}</td>
                    <td>{{ game.wards_bought }}</td>
                    <td>{{ game.css }}</td>
                    <td>{{ game.assists }}</td>
                    <td>{{ game.kda }}</td>
                    <td>{{ game.teamPosition }}</td>
                </tr>
                {% endfor %} <!-- ๋‹ซํž˜ -->
            </tbody>
        </table>
    {% else %}
        <p>๊ฒŒ์ž„ ์ •๋ณด๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.</p>
    {% endif %}

    <a href="/">๋‹ค๋ฅธ ์œ ์ € ๊ฒ€์ƒ‰</a>
</body>
</html>

 

 

 

 

์™„์„ฑ๋œ ์‚ฌ์ดํŠธ์— ์œ ์ € ๋‹‰๋„ค์ž„ ๊ฒ€์ƒ‰ํ•˜๊ธฐ

 

ํŽ˜์ด์ปค๋‹˜์˜ ๋‹‰๋„ค์ž„์œผ๋กœ ๊ฒ€์ƒ‰ํ•ด๋ดค์Šต๋‹ˆ๋‹ค!

์ž˜ ๋‚˜์˜ต๋‹ˆ๋‹ค~!

 

์ด์ œ DB์— ์žˆ๋Š” ์ž๋ฃŒ๋ฅผ ํƒœ๋ธ”๋กœ์™€ ์—ฐ๋™ํ•ด์„œ ์‹œ๊ฐํ™” ํ•œ ๋‹ค์Œ ์›นํŽ˜์ด์ง€์— ๊ตฌํ˜„ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค!