Skip to content

designmeme/python-upbit-api

Folders and files

NameName
Last commit message
Last commit date
May 1, 2023
May 12, 2023
Mar 7, 2025
May 1, 2023
Dec 12, 2024
Apr 28, 2023
Dec 12, 2024
Dec 12, 2024
May 8, 2023
Apr 30, 2023

Repository files navigation

Python Upbit API

๐Ÿ’™ Python Upbit API๋Š” ๊ฐ„๋‹จํ•˜๊ณ  ๋ช…๋ฃŒํ•œ Upbit API Wrapper ์ž…๋‹ˆ๋‹ค. ๐Ÿ‘

Version Supported Python Versions License PyPI Downloads

Installation

pip ๋ช…๋ น์–ด๋กœ ๊ฐ„๋‹จํ•˜๊ฒŒ ์„ค์น˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

pip install python-upbit-api

Quick Start

์ธ์ฆ ์—†์ด ์‚ฌ์šฉํ•˜๊ธฐ

๊ฐ์ข… ์‹œ์„ธ ์ •๋ณด๋ฅผ ์–ป๊ธฐ ์œ„ํ•œ QUOTATION API๋งŒ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ์ธ์ฆ ์ •๋ณด ์—†์ด ์ดˆ๊ธฐํ™” ํ›„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
โš ๏ธ EXCHANGE API๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด upbit.exceptions.ApiKeyError ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

# example.py
from upbit import Upbit

upbit = Upbit()
res = upbit.get_markets()
data = res.json()

upbit.get_accounts() # upbit.exceptions.ApiKeyError ๋ฐœ์ƒ

์ธ์ฆ ์‚ฌ์šฉํ•˜๊ธฐ

์ธ์ฆ์ด ํ•„์š”ํ•œ EXCHANGE API๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค๋ฉด ์ธ์ฆ ์ •๋ณด๋ฅผ ์ดˆ๊ธฐํ™”์‹œ ๋“ฑ๋ก ํ›„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
๐Ÿ™†๐Ÿปโ€โ™€๏ธ QUOTATION API๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

.env ํ™˜๊ฒฝ์„ค์ • ํŒŒ์ผ์— ๋ฐœ๊ธ‰ ๋ฐ›์€ ์ธ์ฆ ์ •๋ณด๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

UPBIT_OPEN_API_ACCESS_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
UPBIT_OPEN_API_SECRET_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# example.py
import os
from upbit import Upbit

access_key = os.environ.get('UPBIT_OPEN_API_ACCESS_KEY')
secret_key = os.environ.get('UPBIT_OPEN_API_SECRET_KEY')
upbit = Upbit(access_key, secret_key)
res = upbit.get_accounts()
data = res.json()

Features

์—…๋น„ํŠธ REST API๋ฅผ ๋ชจ๋‘ ๋ฉ”์„œ๋“œ๋กœ ์ œ๊ณต

์—…๋น„ํŠธ REST API๋ฅผ Upbit ํด๋ž˜์Šค์˜ ๋ฉ”์„œ๋“œ๋กœ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ upbit.py ํŒŒ์ผ ๋‚ด docstring ์ฐธ์กฐ.

๋ฉ”์„œ๋“œ๋ช…
์ž์‚ฐ ์ „์ฒด ๊ณ„์ขŒ ์กฐํšŒ get_accounts
์ฃผ๋ฌธ ์ฃผ๋ฌธ ๊ฐ€๋Šฅ ์ •๋ณด get_order_chance
๊ฐœ๋ณ„ ์ฃผ๋ฌธ ์กฐํšŒ get_order
์ฃผ๋ฌธ ๋ฆฌ์ŠคํŠธ ์กฐํšŒ get_orders
id๋กœ ์ฃผ๋ฌธ๋ฆฌ์ŠคํŠธ ์กฐํšŒ get_orders_by_id
์ฒด๊ฒฐ ๋Œ€๊ธฐ ์ฃผ๋ฌธ (Open Order) ์กฐํšŒ get_open_orders
์ข…๋ฃŒ๋œ ์ฃผ๋ฌธ (Closed Order) ์กฐํšŒ get_closed_orders
์ฃผ๋ฌธ ์ทจ์†Œ ์ ‘์ˆ˜ delete_order
์ฃผ๋ฌธ ์ผ๊ด„ ์ทจ์†Œ ์ ‘์ˆ˜ delete_orders
id๋กœ ์ฃผ๋ฌธ๋ฆฌ์ŠคํŠธ ์ทจ์†Œ ์ ‘์ˆ˜ delete_orders_by_id
์ฃผ๋ฌธํ•˜๊ธฐ create_order
์ถœ๊ธˆ ์ถœ๊ธˆ ๋ฆฌ์ŠคํŠธ ์กฐํšŒ get_withdraws
๊ฐœ๋ณ„ ์ถœ๊ธˆ ์กฐํšŒ get_withdraw
์ถœ๊ธˆ ๊ฐ€๋Šฅ ์ •๋ณด get_withdraw_chance
๋””์ง€ํ„ธ ์ž์‚ฐ ์ถœ๊ธˆํ•˜๊ธฐ create_withdraw_coin
์›ํ™” ์ถœ๊ธˆํ•˜๊ธฐ create_withdraw_krw
์ถœ๊ธˆ ํ—ˆ์šฉ ์ฃผ์†Œ ๋ฆฌ์ŠคํŠธ ์กฐํšŒ get_withdraw_addresses
์ž…๊ธˆ ์ž…๊ธˆ ๋ฆฌ์ŠคํŠธ ์กฐํšŒ get_deposits
๊ฐœ๋ณ„ ์ž…๊ธˆ ์กฐํšŒ get_deposit
์ž…๊ธˆ ์ฃผ์†Œ ์ƒ์„ฑ ์š”์ฒญ create_coin_address
์ „์ฒด ์ž…๊ธˆ ์ฃผ์†Œ ์กฐํšŒ get_coin_addresses
๊ฐœ๋ณ„ ์ž…๊ธˆ ์ฃผ์†Œ ์กฐํšŒ get_coin_address
์›ํ™” ์ž…๊ธˆํ•˜๊ธฐ create_deposit_krw
๊ณ„์ •์ฃผ ํ™•์ธ(ํŠธ๋ž˜๋ธ”๋ฃฐ ๊ฒ€์ฆ)๊ฐ€๋Šฅ ๊ฑฐ๋ž˜์†Œ ๋ฆฌ์ŠคํŠธ ์กฐํšŒ get_vasps
์ž…๊ธˆ UUID๋กœ ํŠธ๋ž˜๋ธ”๋ฃฐ ๊ฒ€์ฆํ•˜๊ธฐ verify_travel_rule_by_uuid
์ž…๊ธˆ TxID๋กœ ํŠธ๋ž˜๋ธ”๋ฃฐ ๊ฒ€์ฆํ•˜๊ธฐ verify_travel_rule_by_txid
์„œ๋น„์Šค ์ •๋ณด ์ž…์ถœ๊ธˆ ํ˜„ํ™ฉ get_wallet_status
API ํ‚ค ๋ฆฌ์ŠคํŠธ ์กฐํšŒ get_api_keys
์‹œ์„ธ ์ข…๋ชฉ ์กฐํšŒ ๋งˆ์ผ“ ์ฝ”๋“œ ์กฐํšŒ get_markets
์‹œ์„ธ ์บ”๋“ค ์กฐํšŒ ์ดˆ(Second) ์บ”๋“ค get_candles_second
๋ถ„(Minute) ์บ”๋“ค get_candles_minute
์ผ(Day) ์บ”๋“ค get_candles_day
์ฃผ(Week) ์บ”๋“ค get_candles_week
์›”(Month) ์บ”๋“ค get_candles_month
์—ฐ(Year) ์บ”๋“ค get_candles_year
์‹œ์„ธ ์ฒด๊ฒฐ ์กฐํšŒ ์ตœ๊ทผ ์ฒด๊ฒฐ ๋‚ด์—ญ get_trades_ticks
์‹œ์„ธ ํ˜„์žฌ๊ฐ€ ์กฐํšŒ ํ˜„์žฌ๊ฐ€ ์ •๋ณด get_ticker
์‹œ์„ธ ํ˜„์žฌ๊ฐ€ ์กฐํšŒ ๋งˆ์ผ“ ๋‹จ์œ„ ํ˜„์žฌ๊ฐ€ ์ •๋ณด get_tickers_by_quote
์‹œ์„ธ ํ˜ธ๊ฐ€ ์กฐํšŒ ํ˜ธ๊ฐ€ ์ •๋ณด get_orderbook
ํ˜ธ๊ฐ€ ๋ชจ์•„๋ณด๊ธฐ ๋‹จ์œ„ ์ •๋ณด get_orderbook_levels

Requests ์‚ฌ์šฉ

Requests ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

  1. requests.Response ๊ฐ์ฒด๋ฅผ ๊ทธ๋Œ€๋กœ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

    # example.py
    from upbit import Upbit
    
    upbit = Upbit()
    res = upbit.get_markets()
    
    data = res.json()
    status_code = res.status_code
  2. requests.adapters.HTTPAdapter ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์žฌ์‹œ๋„ ํšŸ์ˆ˜ ๋“ฑ์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    # example.py
    from upbit import Upbit
    import requests
    
    adapter = requests.adapters.HTTPAdapter(max_retries=3)
    
    upbit = Upbit(http_adapter=adapter)
  3. requests.Session.request ์š”์ฒญ ํŒŒ๋ผ๋ฏธํ„ฐ timeout ๊ฐ’์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    # example.py
    from upbit import Upbit
    
    upbit = Upbit(timeout=(10, 5))  # ๋ชจ๋“  ์š”์ฒญ์— ์„ค์ •ํ•  timeout
    
    res = upbit.get_markets(timeout=10)  # ์ด ์š”์ฒญ์—๋งŒ ์„ค์ •ํ•  timeout

์˜ˆ์™ธ ํด๋ž˜์Šค ์ œ๊ณต

๋ชจ๋“  API ์š”์ฒญ์—์„œ ๋ฐœ์ƒํ•œ requests.exceptions.HTTPError ์˜ˆ์™ธ๋Š” ์ด ์˜ˆ์™ธ๋ฅผ ์ƒ์†ํ•œ upbit.exceptions.UpbitHTTPError ์˜ˆ์™ธ๋กœ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

์•„๋ž˜ Upbit ๊ณต์‹ ๋ฌธ์„œ์— ๊ณต๊ฐœํ•œ ์—๋Ÿฌ ์œ ํ˜•์— ๋งž๋Š” ์˜ˆ์™ธ ์Œ์„ ๊ฐ€์ง‘๋‹ˆ๋‹ค.

# example.py
from upbit import Upbit, TooManyRequests, UpbitClientError, UpbitServerError

upbit = Upbit()
try:
    res = upbit.get_markets()
except TooManyRequests as e:
    status_code = e.response.status_code  # 429
    # ...์˜ˆ์™ธ ์ฒ˜๋ฆฌ ์ฝ”๋“œ
except UpbitClientError as e:
    res = e.response
    # ...์˜ˆ์™ธ ์ฒ˜๋ฆฌ ์ฝ”๋“œ
except UpbitServerError as e:
    res = e.response
    # ...์˜ˆ์™ธ ์ฒ˜๋ฆฌ ์ฝ”๋“œ

์ž”์—ฌ ์š”์ฒญ ์ˆ˜ ํ™•์ธ

์—…๋น„ํŠธ API Remaining-Req ์‘๋‹ต ํ—ค๋”์— ๋‹ด๊ธด ์ž”์—ฌ ์š”์ฒญ ์ˆ˜๋ฅผ upbit.models.RemainingReq ๊ฐ์ฒด๋กœ ์ œ๊ณต๋˜์–ด ์ •๋ณด์— ์‰ฝ๊ฒŒ ์ ‘๊ทผ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์š”์ฒญ ๊ทธ๋ฃน๋ณ„ ์ตœ์‹  ๊ฐ’์„ ํ”„๋กœํผํ‹ฐ์— ์ €์žฅํ•˜๋ฉฐ get_remaining_reqs() ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๊ทธ๋ฃน์˜ ์ตœ์‹  ์ž”์—ฌ ์š”์ฒญ ์ˆ˜ ๊ฐ์ฒด๋ฅผ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ฐธ๊ณ : Exchange API ์ž”์—ฌ ์š”์ฒญ ์ˆ˜ ํ™•์ธ ๋ฐฉ๋ฒ•

# example.py
from upbit import Upbit
from upbit.models import RemainingReq

upbit = Upbit()
res = upbit.get_candles_day('KRW-BTC')
rr: RemainingReq = upbit.get_remaining_reqs('candles')
rr.minute
rr.updated

# ์‘๋‹ต ํ—ค๋”๋„ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉ ๊ฐ€๋Šฅ
rr_text = res.headers['Remaining-Req']  # 'group=candles; min=59; sec=4'

์š”์ฒญ ํŒŒ๋ผ๋ฏธํ„ฐ ๋ชจ๋ธ ์ œ๊ณต

Upbit API ์š”์ฒญ ํŒŒ๋ผ๋ฏธํ„ฐ์— ์‚ฌ์šฉํ•  ๋‹ค์–‘ํ•œ ๋ฐ์ดํ„ฐ ๋ชจ๋ธ์„ ํƒ€์ž…์œผ๋กœ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

# example.py
from upbit.models import OrderSide

# ...

# Type Hint
order_side: OrderSide = 'bid'
res = upbit.create_order(market='KRW-BTC', side=order_side, ord_type='limit', price='100', volume='0.01')

Docstring & Type Hint

์ž˜ ์ž‘์„ฑํ•œ Docstring ๋‚ด์šฉ๊ณผ ํƒ€์ž…์œผ๋กœ IDE์—์„œ ์‚ฌ์šฉํ•˜๊ธฐ ํŽธ๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ๐Ÿ“๐Ÿ’ก

WebSocket

์•„์ง ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ฐธ๊ณ  ์ด์Šˆ

Changelog

์ตœ์‹  ๋ณ€๊ฒฝ ์‚ฌํ•ญ์€ ์•„๋ž˜์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.