Neople Open API wrapper for data analyst


License
MIT
Install
pip install pyneople==0.4.0

Documentation

pyneople

Neople Open API wrapper for data analyst

Documents

pyneople.

Installation

pip install pyneople

Simple Usage

from pyneople.character import CharacterSearch
api_key = "Neople Open API ์—์„œ ๋ฐœ๊ธ‰๋ฐ›์€ API key"
character_search = CharacterSearch(api_key)
data = character_search.get_data("์„œ๋ฒ„์ด๋ฆ„", "์บ๋ฆญํ„ฐ์ด๋ฆ„")
character_search.parse_data(data)

print(character_search.server_id) 
print(character_search.character_name)

Step 0. ์‹œ์ž‘์— ์•ž์„œ

Neople Open API ๊ฐ€์ž… ํ›„ api key ํ™•๋ณดํ•˜๊ธฐ

  1. Neople Open API ์ ‘์† ํ›„ ๋กœ๊ทธ์ธ
  2. ์šฐ์ธก ์ƒ๋‹จ์˜ ๋งˆ์ดํŽ˜์ด์ง€ ํด๋ฆญ
  3. ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋“ฑ๋ก

Step 1. ์บ๋ฆญํ„ฐ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ

pyneople.character ๋‚ด๋ถ€์˜ ํด๋ž˜์Šค๋ฅผ ์ด์šฉํ•ด์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.

from pyneople.character import CharacterInformation
api_key = "Neople Open API ์—์„œ ๋ฐœ๊ธ‰๋ฐ›์€ API key"

# api_key๋ฅผ ์ด์šฉํ•ด ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค
character_info = CharacterInformation(api_key)

# get_data ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค
data = character_info.get_data("cain", "d018e5f7e7519e34b8ef21db0c40fd98")

print(data)

Step 2. ์บ๋ฆญํ„ฐ ๋ฐ์ดํ„ฐ ์ •๋ฆฌํ•˜๊ธฐ

๊ฐ์ฒด์˜ ํ•˜์œ„ ์†์„ฑ์„ ์ƒ์„ฑํ•˜๋„๋ก ๋ฐ์ดํ„ฐ๋ฅผ ์ •๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

์›ํ•˜๋Š” ๋ฐ์ดํ„ฐ๋งŒ ํ•˜์œ„ ์†์„ฑ์œผ๋กœ ์ƒ์„ฑํ•˜๋Š” ํด๋ž˜์Šค ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€์ง€๋Š” ํด๋ž˜์Šค๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. CharacterSearch, CharacterInformation, Status, GrowInfo, BaseEquipment, Equipment, Weapon, Equipments, Avatar, PlatinumAvatar, Avatars

# parse_data ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•ด ๊ฐ€์ ธ์˜จ ๋ฐ์ดํ„ฐ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜์œ„ ์†์„ฑ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
character_info.parse_data(data)

# ์ด์ œ character_info ๊ฐ์ฒด์˜ ํ•˜์œ„ ์†์„ฑ์ด ์ƒ์„ฑ๋˜์–ด ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
print(character_info.character_name)

# pyneople.functions ๋‚ด์˜ attr_flatten ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•ด์„œ ๋ชจ๋“  ํ•˜์œ„ ์†์„ฑ์˜ ์ด๋ฆ„์„ ๋ฆฌ์ŠคํŠธ๋กœ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
from pyneople.functions import attr_flatten
print(attr_flatten(character_info))

# pyneople.functions ๋‚ด์˜ value_flatten ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•ด์„œ ๋ชจ๋“  ํ•˜์œ„ ์†์„ฑ์˜ ๊ฐ’์„ ๋ฆฌ์ŠคํŠธ๋กœ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
from pyneople.functions import value_flatten
print(value_flatten(character_info))

# python ๋‚ด์žฅํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜๋ฉด ํ•˜์œ„ ์†์„ฑ์˜ ์ด๋ฆ„์„ key, ๊ฐ’์„ value๋กœ ๊ฐ€์ง€๋Š” dictionary๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
character_info_dict = dict(zip(attr_flatten(character_info), value_flatten(character_info)))
print(character_info_dict)

Step 3. ์›ํ•˜๋Š” ๋ฐ์ดํ„ฐ๋งŒ ์ •๋ฆฌํ•˜๊ธฐ

๋‹ค์Œ๊ณผ ๊ฐ™์€ ํด๋ž˜์Šค๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. CharacterSearch, CharacterInformation, Status, GrowInfo, BaseEquipment, Equipment, Weapon, Equipments, Avatar, PlatinumAvatar, Avatars

# ํด๋ž˜์Šค ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•ด์„œ ์›ํ•˜๋Š” ๋ฐ์ดํ„ฐ๋งŒ ํ•˜์œ„ ์†์„ฑ์œผ๋กœ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
# set_sub_attributes ์ดํ›„ ๋ชจ๋“  character_infous class ๊ฐ์ฒด๋Š” parse_data ๋ฉ”์„œ๋“œ ์‚ฌ์šฉ์‹œ ์ง€์ •ํ•œ ์ •๋ณด๋งŒ ํ•˜์œ„ ์†์„ฑ์œผ๋กœ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
CharacterInformation.set_sub_attributes(["character_name", 'level', 'job_grow_name'])
del character_info
character_info = CharacterInformation(api_key)
character_info.parse_data(data)
print(attr_flatten(character_info))

# ํ•˜์œ„ ์†์„ฑ์„ ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ์ดˆ๊ธฐํ™” ํ•˜๋ ค๋ฉด init_sub_attributes ํด๋ž˜์Šค ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
CharacterInformation.init_sub_attributes()
del character_info
character_info = CharacterInformation(api_key)
character_info.parse_data(data)
print(attr_flatten(character_info))

Step 4. MongoDB๋กœ ๋ฐ์ดํ„ฐ ์ €์žฅํ•˜๊ธฐ

pymongo์˜ MongoClient๊ฐ์ฒด๋ฅผ ํ™•๋ณด ํ›„ ์ง„ํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

from pyneople.database_connecter import store_fame_data_to_mongodb
from pymongo import MongoClient
mongo_client = MongoClient('mongodb://localhost:27017/')
store_fame_data_to_mongodb(mongo_client, 'dnf', 'fame_tb_20240508', [api_key])

ํ•ด๋‹น ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋˜๋ฉด ๋กœ์ปฌ MongoDB์˜ 'dnf'๋ผ๋Š” ์ด๋ฆ„์„ ๊ฐ€์ง€๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— 'fame_tb_20240508'๋ผ๋Š” ์ด๋ฆ„์„ ๊ฐ€์ง€๋Š” collection์— ์ตœ๊ทผ 90์ผ๊ฐ„ ์ ‘์†๊ธฐ๋ก์ด ์žˆ๋Š” 110๋ ˆ๋ฒจ ์บ๋ฆญํ„ฐ ์ „๋ถ€๋ฅผ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
๋˜ํ•œ api_key๋ฅผ ์—ฌ๋Ÿฌ๊ฐœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋‹ค๋งŒ CPU์˜ ์ฝ”์–ด ์ˆ˜์— ๋”ฐ๋ผ ๋ฐ์ดํ„ฐ ์ˆ˜์ง‘ ์†๋„ ํ–ฅ์ƒ์ด ์ด๋ฃจ์–ด ์งˆ ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ๋„ ์ƒ๊น๋‹ˆ๋‹ค.
CPU ์ฝ”์–ด์ˆ˜ ์ด์ƒ์˜ api key๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

Step 5. PostgreSQL ์กฐ์ž‘ํ•˜๊ธฐ

pyneople.database_connecter์—์„œ PostgreSQL ์กฐ์ž‘์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

from pyneople.database_connecter import PostgreSQLConnecter
# ์ƒ์„ฑ์ž ํ•จ์ˆ˜์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ psycopg2 connectํ•จ์ˆ˜์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์‚ฌ์šฉ๋  dict๋ฅผ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค
# ํ•ด๋‹น dict๋Š” ์˜ˆ์‹œ์ž…๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ ํ•ฉํ•˜๊ฒŒ ์ˆ˜์ • ํ›„ ์ด์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
pg_dict = {
    'host' : 'localhost', 
    'user' : 'dnfdba', 
    'password':'1557', 
    'database':'dnf'
}
pg_connecter = PostgreSQLConnecter(pg_dict)

# ์›ํ•˜๋Š” ์ฟผ๋ฆฌ๋ฌธ์„ ์ž…๋ ฅํ•˜๋ฉด ์‹คํ–‰์‹œ์ผœ์ฃผ๋Š” ๋ฉ”์„œ๋“œ์ž…๋‹ˆ๋‹ค.
query = \
"""
์›ํ•˜๋Š” ์ฟผ๋ฆฌ๋ฌธ์„ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค.
;"""
pg_connecter.excute(query)

# ์›ํ•˜๋Š” ์ฟผ๋ฆฌ๋ฌธ(SELCT)์„ ์ž…๋ ฅํ•˜๋ฉด ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฉ”์„œ๋“œ์ž…๋‹ˆ๋‹ค.
query = \
"""
SELECT * 
FROM table_name
LIMIT 10
;"""
data = pg_connecter.fetch(query)
print(data)

# table์„ ์ƒ์„ฑํ•˜๋Š” ๋ฉ”์„œ๋“œ์ž…๋‹ˆ๋‹ค.
pg_connecter.create_table("timeline_tb_20240502",
            ["total_id VARCHAR(43)",
             "timeline_code SMALLINT",
             "timeline_date TIMESTAMP",
             "timeline_data TEXT"
             ], 
            arg_drop=True)

# table์„ ์ƒ์„ฑํ•˜๋Š” ๋ฉ”์„œ๋“œ์— ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์‚ฌ์šฉ ๋  ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฉ”์„œ๋“œ์ž…๋‹ˆ๋‹ค.
CharacterInformation.set_sub_attributes(["character_name", 'level', 'job_grow_name'])
del character_info
character_info = CharacterInformation(api_key)
data = character_info.get_data("cain", "d018e5f7e7519e34b8ef21db0c40fd98")
character_info.parse_data(data)
pg_connecter.create_table_query(character_info, ['VARCHAR(16)', 'SMALLINT', "VARCHAR(16)"])

# table์˜ ํ•„๋“œ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฉ”์„œ๋“œ์ž…๋‹ˆ๋‹ค.
print(pg_connecter.get_column_names("table_name"))

# table ์ด๋ฆ„์˜ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฉ”์„œ๋“œ์ž…๋‹ˆ๋‹ค.
print(pg_connecter.get_table_name_list())

# table์— ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฝ์ž…ํ•˜๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.
pg_connecter.insert_into_table(
    pg.cursor, 
    "table_name",  
    ["character_name", "level", "job_grow_name"], 
    [("์‘ค๋‚จ", "110", "์ŠคํŠธ๋ผ์ด์ปค")]
    )

Step 6. MongoDB์— ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ๋ฅผ PostgreSQL๋กœ ์ด๋™ํ•˜๊ธฐ

from pyneople.database_connecter import mongodb_to_postgresql
# ์ „์ฒ˜๋ฆฌ ํ•จ์ˆ˜๋ฅผ ๋ฏธ๋ฆฌ ์ •์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค
# ์ „์ฒ˜๋ฆฌ ํ•จ์ˆ˜๋Š” ๋ฐ˜๋“œ์‹œ tuple ๋˜๋Š” tuple์„ ์›์†Œ๋กœ ๊ฐ€์ง€๋Š” list๋ฅผ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
def prepro(document):
    document = document['rows']
    data = []
    for character in document:
        cs.parse_data(character)
        value_flatten(cs)
        data.append(tuple(
            [f"{cs.server_id} {cs.character_id}",
            cs.character_name,
            cs.level,
            cs.job_name,
            cs.job_grow_name,
            cs.fame]
        ))
    return data    
mongodb_to_postgresql(pg_connecter, 'fame_tb_20240501', mongo_client, 'dnf', 'fame_tb_20240502', prepro)