Skip to main content

Modern Python client for the Upbit cryptocurrency exchange API

Project description

Upbeat

Upbit 암호화폐 거래소를 위한 비공식 Python 클라이언트 라이브러리.

Looking for English documentation? See README.en.md.

[!WARNING] 이 라이브러리는 투자 수익을 보장하지 않습니다. 버그, API 변경, 네트워크 장애 등 어떤 원인으로든 발생하는 투자 손실에 대해 일체의 책임을 지지 않습니다. 투자 판단과 결과는 전적으로 사용자 본인에게 있습니다.


손으로 직접 고점에 매수하고 저점에 매도하느라 지치셨나요? 이제 코드로 손실을 자동화하세요!

from upbeat import AsyncUpbeat

async with AsyncUpbeat(access_key="...", secret_key="...") as client:
    # 실시간 시세를 감시하다가...
    async for tick in client.ws.ticker(["KRW-BTC"]):
        change = tick.signed_change_rate  # 전일 대비 변동률

        if change > 0.05:
            # 5% 올랐다! 더 오를 것 같으니 추격 매수 (일명 FOMO)
            await client.orders.create(
                market="KRW-BTC", side="bid",
                ord_type="price", price="100000",
            )

        elif change < -0.03:
            # 3% 빠졌다! 패닉셀!
            btc = await client.shortcuts.get_account("BTC")
            await client.orders.create(
                market="KRW-BTC", side="ask",
                ord_type="market", volume=btc.balance,
            )
        # 이 전략의 기대수익률: -∞

(농담입니다. 제발 이렇게 쓰지 마세요.)

왜 Upbeat?

  • AI 친화적 — OpenAPI 3.1 + AsyncAPI 3.0 스펙이 내장되어 있어서 LLM이나 AI 에이전트가 API 구조를 바로 파악하고 코드를 생성할 수 있습니다.
  • Upbit API 전체 커버리지 — 시세 조회 12개, 거래 31개, WebSocket 6개 채널. 업비트가 제공하는 API를 빠짐없이 지원합니다.
  • 타입 안전성 — 모든 요청과 응답이 Pydantic v2 모델로 정의되어 있어서 IDE 자동완성이 잘 됩니다. 잘못된 파라미터는 실행 전에 잡힙니다.

[!NOTE] 이 프로젝트는 Agentic 코딩으로 개발되었습니다. AI 코딩 에이전트(Claude Code)와 함께 설계, 구현, 테스트를 진행했습니다. 프로젝트 루트의 CLAUDE.mdAGENTS.md에 코드 스타일, 아키텍처, 명령어 등 프로젝트 컨텍스트가 정리되어 있어 AI 에이전트가 바로 기여를 시작할 수 있습니다.

주요 기능

  • Sync + Async 동시 지원 (Upbeat / AsyncUpbeat)
  • REST API 전체 커버리지 (시세 + 거래)
  • WebSocket 실시간 데이터 스트리밍
  • Pydantic v2 기반 타입 안전한 모델
  • 지수 백오프 자동 재시도
  • Remaining-Req 헤더 기반 스마트 Rate Limit 관리
  • JWT 인증 (HS512)
  • 컨텍스트 매니저를 통한 리소스 정리
  • HTTP 클라이언트, 로깅, 타임아웃 커스터마이징

설치

pip install upbeat

pandas 지원 포함:

pip install upbeat[pandas]

빠른 시작

공개 API (인증 불필요)

import upbeat

# 모듈 레벨 편의 함수
ticker = upbeat.get_ticker("KRW-BTC")
candles = upbeat.get_candles("KRW-BTC", interval="1m", count=200)
orderbook = upbeat.get_orderbook("KRW-BTC")
markets = upbeat.get_markets()

클라이언트 인스턴스

from upbeat import Upbeat

with Upbeat(access_key="...", secret_key="...") as client:
    # 시세 조회 (공개)
    tickers = client.quotation.get_tickers("KRW-BTC")

    # 거래 (인증 필요)
    accounts = client.accounts.list()
    order = client.orders.create(
        market="KRW-BTC",
        side="bid",
        ord_type="limit",
        volume="0.001",
        price="50000000",
    )

비동기 클라이언트

from upbeat import AsyncUpbeat

async with AsyncUpbeat(access_key="...", secret_key="...") as client:
    tickers = await client.quotation.get_tickers("KRW-BTC")
    accounts = await client.accounts.list()

WebSocket

from upbeat import AsyncUpbeat

async with AsyncUpbeat(access_key="...", secret_key="...") as client:
    async for msg in client.ws.ticker(["KRW-BTC", "KRW-ETH"]):
        print(msg.trade_price)

설정

from upbeat import Upbeat, Timeout

client = Upbeat(
    access_key="...",
    secret_key="...",
    timeout=Timeout(connect=10.0, read=30.0),
    max_retries=3,
    logger=my_custom_logger,  # Logger Protocol 구현체
)

# 퍼-리퀘스트 오버라이드
cautious_client = client.with_options(max_retries=5)

커스텀 HTTP 클라이언트

import httpx
from upbeat import Upbeat

client = Upbeat(
    access_key="...",
    secret_key="...",
    http_client=httpx.Client(proxy="http://proxy:8080"),
)

에러 처리

from upbeat import Upbeat, RateLimitError, InsufficientFundsError, NotFoundError

client = Upbeat(access_key="...", secret_key="...")

try:
    order = client.orders.create(
        market="KRW-BTC",
        side="bid",
        ord_type="limit",
        volume="0.001",
        price="50000000",
    )
except InsufficientFundsError as e:
    print(f"잔고 부족: {e.error_message}")
except RateLimitError as e:
    print(f"요청 초과. 잔여 횟수: {e.remaining_request}")
except NotFoundError as e:
    print(f"리소스 없음: {e.error_message}")

예외 계층

UpbeatError
  APIError
    APIStatusError
      BadRequestError (400)
      AuthenticationError (401)
      PermissionDeniedError (403)
      NotFoundError (404)
      UnprocessableEntityError (422)
      RateLimitError (418, 429)
      InternalServerError (5xx)
      InsufficientFundsError (400)
      MinimumOrderError (400)
    APIConnectionError
      APITimeoutError
  WebSocketError
    WebSocketConnectionError
    WebSocketClosedError

API 레퍼런스

사용 가능한 리소스 그룹:

리소스 설명 인증
client.quotation 시세 데이터 (현재가, 캔들, 호가, 체결) 불필요
client.markets 페어(거래쌍) 정보 불필요
client.accounts 계정 잔고 필요
client.orders 주문 관리 필요
client.deposits 입금 관련 필요
client.withdrawals 출금 관련 필요
client.ws WebSocket 실시간 스트리밍 채널별 상이

엔드포인트 상세 문서는 OpenAPI 스펙을 참고하세요:

기여

기여는 언제나 환영합니다! PR을 올리기 전에 아래 과정을 따라주세요.

# 1. 포크 후 클론
git clone https://github.com/<your-username>/upbeat.git
cd upbeat

# 2. 의존성 설치
uv sync --group dev

# 3. 브랜치 생성
git checkout -b feat/my-feature

# 4. 코드 작성 후, PR 전에 아래를 모두 통과시켜 주세요
uv run ruff check src/            # 린트
uv run ruff format src/           # 포맷
uv run mypy src/upbeat/           # 타입 체크
uv run pytest                     # 테스트

PR을 올릴 때:

  • 브랜치 이름은 feat/, fix/, chore/ 등 접두사를 사용해 주세요.
  • 커밋 메시지는 변경의 "왜"를 간결하게 담아주세요.
  • 새로운 기능에는 테스트를 함께 추가해 주세요.
  • 린트, 포맷, 타입 체크, 테스트가 모두 통과하는지 확인해 주세요.

라이선스

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

upbeat-0.1.0.tar.gz (27.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

upbeat-0.1.0-py3-none-any.whl (41.2 kB view details)

Uploaded Python 3

File details

Details for the file upbeat-0.1.0.tar.gz.

File metadata

  • Download URL: upbeat-0.1.0.tar.gz
  • Upload date:
  • Size: 27.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.10.9 {"installer":{"name":"uv","version":"0.10.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for upbeat-0.1.0.tar.gz
Algorithm Hash digest
SHA256 e3dc849bf561152f0a85df23d04362f95c071c37b13c515abd4cb11296f9ae4f
MD5 d1bbe13e258dbe9c3f77db141b5aae1e
BLAKE2b-256 1a880e442f40ee6e30bbce1d0a8ee5ca0d34d1889577e61653a17ac83042d2e3

See more details on using hashes here.

File details

Details for the file upbeat-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: upbeat-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 41.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.10.9 {"installer":{"name":"uv","version":"0.10.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for upbeat-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 45affd42a21b82ad1e32849dd01bbdd06499db5a3db02419b045cbadef77c3da
MD5 361219916bb88d86914b8e8f9823d9f7
BLAKE2b-256 ff1c0fb1386ede8b8a2c1bed7f40506bf24db6ee32370f0057f831dd58d88d49

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page