MapleStory

MapleStory OpenAPI Python Client Library


Keywords
maplestory, api, api-wrapper, api-client, nexon-openapi
License
MIT
Install
pip install MapleStory==1.0.1

Documentation

MapleStory OpenAPI Python Client Library

A simple, but extensible Python implementation for the MapleStory OpenAPI.

PyPI - Python Version PyPI - Version Test with pytest codecov


Note

This library can only query data from the KMS(Korea MapleStory).


Overview

This library simplifies access to MapleStory's OpenAPI in Python, enabling queries of character, union, guild, and ranking information, as well as checks on Star Force, cubes, and potential abilities.

Installation

If you are using pip:

pip install maplestory

If you are using poetry:

poetry add maplestory

Supported Python Versions

Python 3.11 and 3.12 are fully supported and tested. While it may operate on subsequent versions of Python 3, testing against these newer versions is not currently conducted.

Unsupported Python Versions

  • Python < 3.11

Third Party Libraries and Dependencies

The following libraries will be installed when you install the client library:

Usage

API credentials

To use the MapleStory OpenAPI, you first need to create a Nexon account at https://www.nexon.com. After creating your account, proceed to the NEXON OPEN API site and create a new application. Once your application is created, copy the API Key and set it as an environment variable or enter it into a .env file within your project.

# set environment variable
MAPLESTORY_OPENAPI_KEY=INSERT_YOUR_KEY_HERE

Examples

Only the names, such as character names and guild names, are required.

If you wish to query a specific date in the past, you can also enter the date. By default, the query is based on the date of yesterday. (The plan is to detail this further by API type in the future.)

Character

You can query all character data using just the character name using Character class.

>>> from mapletory.services.character import Character
>>> char = Character(name="์˜จ์•ค์˜จ")

>>> print(char)
CharacterBasic(
    date=datetime.datetime(2024, 2, 10, 0, 0, tzinfo=TzInfo(+09:00)),
    name='์˜จ์•ค์˜จ',
    world='์Šค์นด๋‹ˆ์•„',
    gender='์—ฌ',
    job='์•„ํฌ๋ฉ”์ด์ง€(์ฌ,์ฝœ)',
    job_level=6,
    level=280,
    exp=29014907373569,
    exp_rate=86.232,
    guild_name='์˜จ์•ค์˜จ',
    image=<PIL.PngImagePlugin.PngImageFile image mode=RGBA size=96x96 at 0x1063C16D0>
)

>>> print(char.ability)
Ability(
    date=datetime.datetime(2024, 2, 4, 0, 0, tzinfo=TzInfo(+09:00)),
    grade='๋ ˆ์ „๋“œ๋ฆฌ',
    info=[
        AbilityInfoItem(grade='๋ ˆ์ „๋“œ๋ฆฌ', value='๋ฒ„ํ”„ ์Šคํ‚ฌ์˜ ์ง€์† ์‹œ๊ฐ„ 50% ์ฆ๊ฐ€'),
        AbilityInfoItem(grade='์œ ๋‹ˆํฌ', value='์ƒํƒœ ์ด์ƒ์— ๊ฑธ๋ฆฐ ๋Œ€์ƒ ๊ณต๊ฒฉ ์‹œ ๋ฐ๋ฏธ์ง€ 8% ์ฆ๊ฐ€'),
        AbilityInfoItem(grade='์œ ๋‹ˆํฌ', value='๋ณด์Šค ๋ชฌ์Šคํ„ฐ ๊ณต๊ฒฉ ์‹œ ๋ฐ๋ฏธ์ง€ 10% ์ฆ๊ฐ€')
    ],
    remain_fame=465283,
    preset_no=1,
    preset1=AbilityPreset(
        grade='๋ ˆ์ „๋“œ๋ฆฌ',
        info=[
            AbilityInfoItem(grade='๋ ˆ์ „๋“œ๋ฆฌ', value='๋ฒ„ํ”„ ์Šคํ‚ฌ์˜ ์ง€์† ์‹œ๊ฐ„ 50% ์ฆ๊ฐ€'),
            AbilityInfoItem(grade='์œ ๋‹ˆํฌ', value='์ƒํƒœ ์ด์ƒ์— ๊ฑธ๋ฆฐ ๋Œ€์ƒ ๊ณต๊ฒฉ ์‹œ ๋ฐ๋ฏธ์ง€ 8% ์ฆ๊ฐ€'),
            AbilityInfoItem(grade='์œ ๋‹ˆํฌ', value='๋ณด์Šค ๋ชฌ์Šคํ„ฐ ๊ณต๊ฒฉ ์‹œ ๋ฐ๋ฏธ์ง€ 10% ์ฆ๊ฐ€')
        ]
    ),
    preset2=AbilityPreset(
        grade='๋ ˆ์ „๋“œ๋ฆฌ',
        info=[
            AbilityInfoItem(grade='๋ ˆ์ „๋“œ๋ฆฌ', value='์•„์ดํ…œ ๋“œ๋กญ๋ฅ  19% ์ฆ๊ฐ€'),
            AbilityInfoItem(grade='์—ํ”ฝ', value='๋ฒ„ํ”„ ์Šคํ‚ฌ์˜ ์ง€์† ์‹œ๊ฐ„ 19% ์ฆ๊ฐ€'),
            AbilityInfoItem(grade='์œ ๋‹ˆํฌ', value='๋ฉ”์†Œ ํš๋“๋Ÿ‰ 15% ์ฆ๊ฐ€')
        ]
    ),
    preset3=AbilityPreset(
        grade='์—ํ”ฝ',
        info=[
            AbilityInfoItem(grade='์—ํ”ฝ', value='๋ชจ๋“  ๋Šฅ๋ ฅ์น˜ 15 ์ฆ๊ฐ€'),
            AbilityInfoItem(grade='๋ ˆ์–ด', value='๋ชจ๋“  ๋Šฅ๋ ฅ์น˜ 5 ์ฆ๊ฐ€'),
            AbilityInfoItem(grade='๋ ˆ์–ด', value='๋ชจ๋“  ๋Šฅ๋ ฅ์น˜ 5 ์ฆ๊ฐ€')
        ]
    )
)
Gulid

To query guild information, you only need the guild name and the world name to which the guild belongs.

>>> from mapletory.services.guild import Guild
>>> guild = Guild(name="๋ฆฌ๋”", world="์Šค์นด๋‹ˆ์•„")

>>> print(guild)
Guild(
    name='๋ฆฌ๋”',
    world='์Šค์นด๋‹ˆ์•„',
    id='789b457f357ce6ac3e1bfa1c95ccaac6',
    basic=GuildBasic(
        date=datetime.datetime(2024, 2, 7, 0, 0, tzinfo=TzInfo(+09:00)),
        world='์Šค์นด๋‹ˆ์•„',
        name='๋ฆฌ๋”',
        level=29,
        fame=65312548,
        point=10000000,
        master_name='์•„๋ธ',
        member_count=160,
        members=[
            '์•„๋ธ',
            '์ถฉ์‹ ์ •๋Ÿญ์ด1',
            '์ถฉ์‹ ์ •๋Ÿญ์ด2',
            ...
        ],
        skills=[
            GuildSkill(
                name='์žฅ์‚ฌ๊พผ',
                description='[๋งˆ์Šคํ„ฐ ๋ ˆ๋ฒจ : 3]\r\n์ƒ์ ์—์„œ ๋ฌผ๊ฑด์„ ๊ตฌ๋งค ์‹œ ์‹ธ๊ฒŒ ์‚ด ์ˆ˜ ์žˆ๋‹ค. ๋‹จ, ์ผ๋ถ€ ์•„์ดํ…œ์—๋Š” ์ ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค.\n[ํ•„์š” ์กฐ๊ฑด]: ๊ธธ๋“œ 10๋ ˆ๋ฒจ ์ด์ƒ\n[ํ•„์š” ์Šคํ‚ฌ]: ์ž”๋ˆ์ด ๋ˆˆ์— ๋„๋„ค 3๋ ˆ๋ฒจ ์ด์ƒ',
                level=3,
                effect='์ƒ์ ์—์„œ ๋ฌผ๊ฑด ๊ตฌ๋งค ์‹œ 4% ์‹ธ๊ฒŒ ๊ตฌ๋งค ๊ฐ€๋Šฅ. ๋‹จ, ํŒ๋งค ๊ฐ€๊ฒฉ ๋Œ€๋น„ ๊ตฌ๋งค ๊ฐ€๊ฒฉ์ด 70% ์ด์ƒ์ผ ๊ฒฝ์šฐ ์ ์šฉ๋˜์ง€ ์•Š์Œ',
                icon=Url('https://open.api.nexon.com/static/maplestory/SkillIcon/KFGDLHOBMI.png')
            ),
            ...
        ],
        noblesse_skills=[
            GuildSkill(
                name='๋ณด์Šค ํ‚ฌ๋ง ๋จธ์‹ ',
                description='[๋งˆ์Šคํ„ฐ ๋ ˆ๋ฒจ : 15]\r\n์ผ์ • ์‹œ๊ฐ„ ๋™์•ˆ ๋ณด์Šค ๋ชฌ์Šคํ„ฐ ๊ณต๊ฒฉ ์‹œ ๋ฐ๋ฏธ์ง€๊ฐ€ ์ฆ๊ฐ€ํ•œ๋‹ค.',
                level=15,
                effect='30๋ถ„ ๋™์•ˆ ๋ณด์Šค ๋ชฌ์Šคํ„ฐ ๊ณต๊ฒฉ ์‹œ ๋ฐ๋ฏธ์ง€ 30% ์ฆ๊ฐ€, ์žฌ์‚ฌ์šฉ ๋Œ€๊ธฐ์‹œ๊ฐ„ 60๋ถ„',
                icon=Url('https://open.api.nexon.com/static/maplestory/SkillIcon/KFGDLHPBOC.png')
            ),
            ...
        ],
        mark=<PIL.PngImagePlugin.PngImageFile image mode=RGBA size=17x17 at 0x10C9C04D0>,
        is_custom_mark=True
    )
)
Union

Raider effects, occupation effects, and artifact effects each show a summarized result.

For example, if there are two instances of STR 100 increase, it will be shown as STR 200 increase.

In addition, STR, DEX, LUK 40 increase is broken down into STR 40 increase, DEX 40 increase, LUK 40 increase, and Attack/Magic Attack 20 increase is calculated as Attack 20 increase, Magic Attack 20 increase.

However, options that ignore defense rate are not combined due to multiplicative application. (Plans are to provide ignored defense rate calculations in a multiplicative manner in the future.)

>>> from maplestory.services.union import Union
>>> union = Union(character_name="์˜จ์•ค์˜จ")
>>> print(union)
Union(
    character_name='์˜จ์•ค์˜จ',
    date=datetime.datetime(2024, 2, 9, 9, 59, 37, 37959, tzinfo=zoneinfo.ZoneInfo(key='Asia/Seoul')),
    level=8870,
    grade='๊ทธ๋žœ๋“œ ๋งˆ์Šคํ„ฐ ์œ ๋‹ˆ์˜จ 2',
    raider_stats=UnionStats(
        [
            UnionStat(stat='DEX 320 ์ฆ๊ฐ€'),
            UnionStat(stat='INT 660 ์ฆ๊ฐ€'),
            UnionStat(stat='LUK 440 ์ฆ๊ฐ€'),
            UnionStat(stat='STR 440 ์ฆ๊ฐ€'),
            UnionStat(stat='๊ฒฝํ—˜์น˜ ํš๋“๋Ÿ‰ 10% ์ฆ๊ฐ€'),
            UnionStat(stat='๊ณต๊ฒฉ ์‹œ 20%์˜ ํ™•๋ฅ ๋กœ ๋ฐ๋ฏธ์ง€ 16% ์ฆ๊ฐ€'),
            UnionStat(stat='๊ณต๊ฒฉ๋ ฅ 20 ์ฆ๊ฐ€'),
            UnionStat(stat='๋งˆ๋ ฅ 20 ์ฆ๊ฐ€'),
            UnionStat(stat='๋ฉ”์†Œ ํš๋“๋Ÿ‰ 4% ์ฆ๊ฐ€'),
            UnionStat(stat='๋ฐฉ์–ด์œจ ๋ฌด์‹œ 5% ์ฆ๊ฐ€'),
            UnionStat(stat='๋ฒ„ํ”„ ์ง€์†์‹œ๊ฐ„ 20% ์ฆ๊ฐ€'),
            UnionStat(stat='๋ณด์Šค ๋ชฌ์Šคํ„ฐ ๊ณต๊ฒฉ ์‹œ ๋ฐ๋ฏธ์ง€ 5% ์ฆ๊ฐ€'),
            UnionStat(stat='์ƒํƒœ ์ด์ƒ ๋‚ด์„ฑ 4 ์ฆ๊ฐ€'),
            UnionStat(stat='์Šคํ‚ฌ ์žฌ์‚ฌ์šฉ ๋Œ€๊ธฐ์‹œ๊ฐ„ 5% ๊ฐ์†Œ'),
            UnionStat(stat='์  ๊ณต๊ฒฉ๋งˆ๋‹ค 70%์˜ ํ™•๋ฅ ๋กœ ์ˆœ์ˆ˜ MP์˜ 8% ํšŒ๋ณต'),
            UnionStat(stat='์ตœ๋Œ€ MP 6% ์ฆ๊ฐ€'),
            UnionStat(stat='ํฌ๋ฆฌํ‹ฐ์ปฌ ๋ฐ๋ฏธ์ง€ 5% ์ฆ๊ฐ€'),
            UnionStat(stat='ํฌ๋ฆฌํ‹ฐ์ปฌ ํ™•๋ฅ  8% ์ฆ๊ฐ€')
        ]
    ),
    occupied_stats=UnionStats(
        [
            UnionStat(stat='INT 25 ์ฆ๊ฐ€'),
            UnionStat(stat='LUK 5 ์ฆ๊ฐ€'),
            UnionStat(stat='๋งˆ๋ ฅ 5 ์ฆ๊ฐ€'),
            UnionStat(stat='๋ฐฉ์–ด์œจ ๋ฌด์‹œ 33% ์ฆ๊ฐ€'),
            UnionStat(stat='๋ฒ„ํ”„ ์ง€์†์‹œ๊ฐ„ 40% ์ฆ๊ฐ€'),
            UnionStat(stat='๋ณด์Šค ๋ชฌ์Šคํ„ฐ ๊ณต๊ฒฉ ์‹œ ๋ฐ๋ฏธ์ง€ 23% ์ฆ๊ฐ€'),
            UnionStat(stat='ํฌ๋ฆฌํ‹ฐ์ปฌ ๋ฐ๋ฏธ์ง€ 20.00% ์ฆ๊ฐ€'),
            UnionStat(stat='ํฌ๋ฆฌํ‹ฐ์ปฌ ํ™•๋ฅ  11% ์ฆ๊ฐ€')
        ]
    ),
    artifact_effects=[
        UnionArtifactEffect(name='์˜ฌ์Šคํƒฏ 150 ์ฆ๊ฐ€', level=10),
        UnionArtifactEffect(name='๊ณต๊ฒฉ๋ ฅ 18, ๋งˆ๋ ฅ 18 ์ฆ๊ฐ€', level=6),
        UnionArtifactEffect(name='๋ฐ๋ฏธ์ง€ 15.00% ์ฆ๊ฐ€', level=10),
        UnionArtifactEffect(name='๋ณด์Šค ๋ชฌ์Šคํ„ฐ ๊ณต๊ฒฉ ์‹œ ๋ฐ๋ฏธ์ง€ 15.00% ์ฆ๊ฐ€', level=10),
        UnionArtifactEffect(name='๋ชฌ์Šคํ„ฐ ๋ฐฉ์–ด์œจ ๋ฌด์‹œ 20% ์ฆ๊ฐ€', level=10),
        UnionArtifactEffect(name='๋ฒ„ํ”„ ์ง€์†์‹œ๊ฐ„ 20% ์ฆ๊ฐ€', level=10),
        UnionArtifactEffect(name='์•„์ดํ…œ ๋“œ๋กญ๋ฅ  7% ์ฆ๊ฐ€', level=6),
        UnionArtifactEffect(name='ํฌ๋ฆฌํ‹ฐ์ปฌ ํ™•๋ฅ  20% ์ฆ๊ฐ€', level=10),
        UnionArtifactEffect(name='ํฌ๋ฆฌํ‹ฐ์ปฌ ๋ฐ๋ฏธ์ง€ 2.40% ์ฆ๊ฐ€', level=6)
    ]
)

You can also access attributes in Korean.

  • ๊ณต๊ฒฉ๋Œ€์›ํšจ๊ณผ
  • ๊ณต๊ฒฉ๋Œ€์ ๋ นํšจ๊ณผ
  • ์•„ํ‹ฐํŒฉํŠธํšจ๊ณผ
>>> print(union.๊ณต๊ฒฉ๋Œ€์›ํšจ๊ณผ)
UnionStats(
    [
        UnionStat('DEX 320 ์ฆ๊ฐ€'),
        UnionStat('INT 660 ์ฆ๊ฐ€'),
        UnionStat('LUK 440 ์ฆ๊ฐ€'),
        UnionStat('STR 440 ์ฆ๊ฐ€'),
        UnionStat('๊ฒฝํ—˜์น˜ ํš๋“๋Ÿ‰ 10% ์ฆ๊ฐ€'),
        UnionStat('๊ณต๊ฒฉ ์‹œ 20%์˜ ํ™•๋ฅ ๋กœ ๋ฐ๋ฏธ์ง€ 16% ์ฆ๊ฐ€'),
        UnionStat('๊ณต๊ฒฉ๋ ฅ 20 ์ฆ๊ฐ€'),
        UnionStat('๋งˆ๋ ฅ 20 ์ฆ๊ฐ€'),
        UnionStat('๋ฉ”์†Œ ํš๋“๋Ÿ‰ 4% ์ฆ๊ฐ€'),
        UnionStat('๋ฐฉ์–ด์œจ ๋ฌด์‹œ 5% ์ฆ๊ฐ€'),
        UnionStat('๋ฒ„ํ”„ ์ง€์†์‹œ๊ฐ„ 20% ์ฆ๊ฐ€'),
        UnionStat('๋ณด์Šค ๋ชฌ์Šคํ„ฐ ๊ณต๊ฒฉ ์‹œ ๋ฐ๋ฏธ์ง€ 5% ์ฆ๊ฐ€'),
        UnionStat('์ƒํƒœ ์ด์ƒ ๋‚ด์„ฑ 4 ์ฆ๊ฐ€'),
        UnionStat('์Šคํ‚ฌ ์žฌ์‚ฌ์šฉ ๋Œ€๊ธฐ์‹œ๊ฐ„ 5% ๊ฐ์†Œ'),
        UnionStat('์  ๊ณต๊ฒฉ๋งˆ๋‹ค 70%์˜ ํ™•๋ฅ ๋กœ ์ˆœ์ˆ˜ MP์˜ 8% ํšŒ๋ณต'),
        UnionStat('์ตœ๋Œ€ MP 6% ์ฆ๊ฐ€'),
        UnionStat('ํฌ๋ฆฌํ‹ฐ์ปฌ ๋ฐ๋ฏธ์ง€ 5% ์ฆ๊ฐ€'),
        UnionStat('ํฌ๋ฆฌํ‹ฐ์ปฌ ํ™•๋ฅ  8% ์ฆ๊ฐ€')
    ]
)

>>> print(union.๊ณต๊ฒฉ๋Œ€์ ๋ นํšจ๊ณผ)
UnionStats(
    [
        UnionStat('INT 25 ์ฆ๊ฐ€'),
        UnionStat('LUK 5 ์ฆ๊ฐ€'),
        UnionStat('๋งˆ๋ ฅ 5 ์ฆ๊ฐ€'),
        UnionStat('๋ฐฉ์–ด์œจ ๋ฌด์‹œ 33% ์ฆ๊ฐ€'),
        UnionStat('๋ฒ„ํ”„ ์ง€์†์‹œ๊ฐ„ 40% ์ฆ๊ฐ€'),
        UnionStat('๋ณด์Šค ๋ชฌ์Šคํ„ฐ ๊ณต๊ฒฉ ์‹œ ๋ฐ๋ฏธ์ง€ 23% ์ฆ๊ฐ€'),
        UnionStat('ํฌ๋ฆฌํ‹ฐ์ปฌ ๋ฐ๋ฏธ์ง€ 20.00% ์ฆ๊ฐ€'),
        UnionStat('ํฌ๋ฆฌํ‹ฐ์ปฌ ํ™•๋ฅ  11% ์ฆ๊ฐ€')
    ]
)

>>> print(union.์•„ํ‹ฐํŒฉํŠธํšจ๊ณผ)
[
    UnionArtifactEffect(name='์˜ฌ์Šคํƒฏ 150 ์ฆ๊ฐ€', level=10),
    UnionArtifactEffect(name='๊ณต๊ฒฉ๋ ฅ 18, ๋งˆ๋ ฅ 18 ์ฆ๊ฐ€', level=6),
    UnionArtifactEffect(name='๋ฐ๋ฏธ์ง€ 15.00% ์ฆ๊ฐ€', level=10),
    UnionArtifactEffect(name='๋ณด์Šค ๋ชฌ์Šคํ„ฐ ๊ณต๊ฒฉ ์‹œ ๋ฐ๋ฏธ์ง€ 15.00% ์ฆ๊ฐ€', level=10),
    UnionArtifactEffect(name='๋ชฌ์Šคํ„ฐ ๋ฐฉ์–ด์œจ ๋ฌด์‹œ 20% ์ฆ๊ฐ€', level=10),
    UnionArtifactEffect(name='๋ฒ„ํ”„ ์ง€์†์‹œ๊ฐ„ 20% ์ฆ๊ฐ€', level=10),
    UnionArtifactEffect(name='์•„์ดํ…œ ๋“œ๋กญ๋ฅ  7% ์ฆ๊ฐ€', level=6),
    UnionArtifactEffect(name='ํฌ๋ฆฌํ‹ฐ์ปฌ ํ™•๋ฅ  20% ์ฆ๊ฐ€', level=10),
    UnionArtifactEffect(name='ํฌ๋ฆฌํ‹ฐ์ปฌ ๋ฐ๋ฏธ์ง€ 2.40% ์ฆ๊ฐ€', level=6)
]