설치
Copy
pip install sajuapi
빠른 시작
Copy
from sajuapi import SajuClient, SajuCalculator
# 클라이언트 초기화
client = SajuClient(api_key="bs_live_xxx")
# 사주 계산 (로컬 실행)
saju = SajuCalculator.calculate(
year=1990,
month=5,
day=15,
hour=14,
gender="male"
)
# 일일 운세 조회
fortune = client.get_daily_fortune(
saju=saju,
user_name="홍길동",
model="haiku"
)
print(fortune.today_fortune.score) # 78
설정
Copy
client = SajuClient(
api_key="bs_live_xxx",
base_url="https://api.sajuapi.dev", # 선택
timeout=30, # 초
max_retries=3
)
# 또는 환경 변수 사용
import os
os.environ["SAJU_API_KEY"] = "bs_live_xxx"
client = SajuClient() # 환경 변수에서 읽음
SajuCalculator
로컬에서 사주팔자 계산:Copy
from sajuapi import SajuCalculator
saju = SajuCalculator.calculate(
year=1990,
month=5,
day=15,
hour=14, # 24시간 형식, 모르면 None
minute=30, # 선택
gender="male",
calendar_type="solar" # "solar" 또는 "lunar"
)
# 사주 접근
print(saju.pillars.day.stem.hangul) # "병"
print(saju.day_master.element) # "fire"
print(saju.element_balance.weakest) # "water"
API 메서드
get_daily_fortune
Copy
fortune = client.get_daily_fortune(
saju=saju,
user_name="홍길동",
model="haiku", # "haiku", "sonnet", "gpt4o"
date="2024-01-15", # 선택
fortune_type="all" # "all", "fortune_only", "character"
)
# 응답 접근
print(fortune.character.day_master) # "병화"
print(fortune.character.emoji) # "☀️"
print(fortune.today_fortune.score) # 78
print(fortune.today_fortune.overall_analysis) # "오늘은..."
for item in fortune.today_fortune.action_items:
print(f"{'✓' if item.type == 'do' else '✕'} {item.text}")
stream_daily_fortune
Copy
from sajuapi import FortuneStream
stream = client.stream_daily_fortune(
saju=saju,
user_name="홍길동"
)
for event in stream:
if event.type == "character":
print(f"성격: {event.data.day_master}")
elif event.type == "tendency":
print(f"위험 감수성: {event.data.scores.risk_tolerance}")
elif event.type == "fortune":
print(f"점수: {event.data.score}")
elif event.type == "complete":
print("모든 데이터 로드됨!")
비동기 지원
Copy
import asyncio
from sajuapi import AsyncSajuClient
async def main():
client = AsyncSajuClient(api_key="bs_live_xxx")
fortune = await client.get_daily_fortune(
saju=saju,
user_name="홍길동"
)
print(fortune.today_fortune.score)
await client.close()
asyncio.run(main())
에러 처리
Copy
from sajuapi import SajuClientError, RateLimitError, AuthenticationError
try:
fortune = client.get_daily_fortune(saju=saju, user_name="홍길동")
except RateLimitError as e:
print(f"요청 제한됨. {e.retry_after}초 후 재시도")
time.sleep(e.retry_after)
except AuthenticationError as e:
print(f"인증 에러: {e.message}")
except SajuClientError as e:
print(f"API 에러 [{e.code}]: {e.message}")
print(f"요청 ID: {e.request_id}")
데이터 클래스
Copy
from sajuapi.types import (
Saju,
Pillar,
FortuneResponse,
CharacterData,
TodayFortune,
ActionItem
)
# 타입 힌트로 IDE 자동완성 지원
def process_fortune(fortune: FortuneResponse) -> None:
score: int = fortune.today_fortune.score
items: list[ActionItem] = fortune.today_fortune.action_items
Django 통합
Copy
# views.py
from django.http import JsonResponse
from sajuapi import SajuClient, SajuCalculator
from django.conf import settings
client = SajuClient(api_key=settings.SAJU_API_KEY)
def get_fortune(request):
data = json.loads(request.body)
saju = SajuCalculator.calculate(
year=data["year"],
month=data["month"],
day=data["day"],
hour=data.get("hour"),
gender=data["gender"]
)
fortune = client.get_daily_fortune(
saju=saju,
user_name=data["userName"]
)
return JsonResponse(fortune.to_dict())
FastAPI 통합
Copy
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from sajuapi import AsyncSajuClient, SajuCalculator
app = FastAPI()
client = AsyncSajuClient()
class FortuneRequest(BaseModel):
year: int
month: int
day: int
hour: int | None = None
gender: str
user_name: str
@app.post("/fortune")
async def get_fortune(request: FortuneRequest):
saju = SajuCalculator.calculate(
year=request.year,
month=request.month,
day=request.day,
hour=request.hour,
gender=request.gender
)
fortune = await client.get_daily_fortune(
saju=saju,
user_name=request.user_name
)
return fortune.to_dict()
Redis 캐싱
Copy
import redis
import json
from datetime import date
redis_client = redis.Redis()
def get_fortune_cached(saju, user_name):
cache_key = f"fortune:{saju.day_master.stem}:{date.today()}"
cached = redis_client.get(cache_key)
if cached:
return json.loads(cached)
fortune = client.get_daily_fortune(saju=saju, user_name=user_name)
redis_client.setex(cache_key, 86400, json.dumps(fortune.to_dict()))
return fortune