Skip to main content
Core.Today

Best Practices

프로덕션 환경을 위한 API 사용 모범 사례와 최적화 팁

1. 인증 & 보안

API 키 관리

API 키를 코드에 직접 넣지 마세요

API 키가 Git에 커밋되면 보안 위험이 발생합니다. 항상 환경 변수나 시크릿 매니저를 사용하세요.

Bad

# API 키를 코드에 직접 입력
API_KEY = "cdt_abc123..."

Good

# 환경 변수에서 읽기
import os
API_KEY = os.environ["CORE_API_KEY"]

팀용 키 분리

개발/스테이징/프로덕션 환경별로 API 키를 분리하세요. 각 키에 설명을 추가해 용도를 명확히 하세요.

환경키 이름용도
Developmentdev-local로컬 개발용
Stagingstaging-ciCI/CD 테스트용
Productionprod-backend프로덕션 서버용

2. 에러 처리 & 재시도

네트워크 오류나 일시적 서버 오류에 대비해 지수 백오프(exponential backoff) 재시도 로직을 구현하세요.

import time
import requests
from requests.exceptions import RequestException

def call_api_with_retry(url, headers, data, max_retries=3):
    """지수 백오프로 API 호출"""
    for attempt in range(max_retries):
        try:
            response = requests.post(url, headers=headers, json=data)
            response.raise_for_status()
            return response.json()
        except RequestException as e:
            if attempt == max_retries - 1:
                raise

            # 지수 백오프: 1초, 2초, 4초...
            wait_time = 2 ** attempt
            print(f"Retry {attempt + 1}/{max_retries} after {wait_time}s: {e}")
            time.sleep(wait_time)

# 사용 예시
result = call_api_with_retry(
    "https://api.core.today/v1/predictions",
    headers={"X-API-Key": API_KEY, "Content-Type": "application/json"},
    data={"model": "flux-schnell", "input": {"prompt": "..."}}
)

재시도해야 할 상태 코드

  • 408 - Request Timeout
  • 429 - Too Many Requests (Rate Limit)
  • 500, 502, 503, 504 - 서버 오류

3. Rate Limiting 대응

API에는 분당 요청 제한이 있습니다. 429 응답을 받으면 Retry-After 헤더를 확인하세요.

플랜분당 요청동시 작업
Free60 req/min5
Pro300 req/min20
EnterpriseCustomCustom
# Rate Limit 헤더 확인
response = requests.get(url, headers=headers)

remaining = response.headers.get("X-RateLimit-Remaining")
reset_time = response.headers.get("X-RateLimit-Reset")

if response.status_code == 429:
    retry_after = int(response.headers.get("Retry-After", 60))
    print(f"Rate limited. Waiting {retry_after} seconds...")
    time.sleep(retry_after)

4. 효율적인 폴링

비동기 작업의 상태를 확인할 때는 적절한 간격으로 폴링하세요.

모델별 권장 폴링 간격

  • 이미지 (FLUX Schnell)1초
  • 이미지 (FLUX Pro)2초
  • 비디오 (짧은)5초
  • 비디오 (긴)10초

폴링 최적화 팁

  • - 적응형 폴링: 처음 짧게, 점점 길게
  • - 최대 폴링 횟수 설정
  • - 타임아웃 설정
  • - Webhook 사용 권장
import time

def poll_with_backoff(job_id, initial_interval=1, max_interval=10, timeout=300):
    """적응형 폴링: 점점 간격을 늘림"""
    start_time = time.time()
    interval = initial_interval

    while True:
        result = get_prediction(job_id)

        if result["status"] in ["succeeded", "failed"]:
            return result

        if time.time() - start_time > timeout:
            raise TimeoutError(f"Job {job_id} timed out")

        time.sleep(interval)
        interval = min(interval * 1.5, max_interval)  # 간격 점점 증가

5. Webhook 활용

폴링 대신 Webhook을 사용하세요

Webhook을 사용하면 폴링 없이 작업 완료 알림을 실시간으로 받을 수 있습니다.

Webhook 설정

{
  "model": "flux-schnell",
  "input": {
    "prompt": "A beautiful landscape"
  },
  "webhook": "https://your-server.com/api/webhook",
  "webhook_events": ["completed", "failed"]
}

Webhook 수신 처리

from flask import Flask, request
import hmac
import hashlib

app = Flask(__name__)
WEBHOOK_SECRET = os.environ["WEBHOOK_SECRET"]

@app.route("/api/webhook", methods=["POST"])
def handle_webhook():
    # 서명 검증
    signature = request.headers.get("X-Webhook-Signature")
    payload = request.get_data()

    expected = hmac.new(
        WEBHOOK_SECRET.encode(),
        payload,
        hashlib.sha256
    ).hexdigest()

    if not hmac.compare_digest(signature, expected):
        return {"error": "Invalid signature"}, 401

    # 이벤트 처리
    data = request.json
    job_id = data["id"]
    status = data["status"]

    if status == "succeeded":
        output_url = data["output"][0]
        # 결과 처리...
    elif status == "failed":
        error = data.get("error")
        # 에러 처리...

    return {"received": True}

6. 비용 최적화

비용 절감 팁

  • 개발/테스트 시 저렴한 모델 사용 (FLUX Schnell)
  • 비디오는 짧은 길이로 먼저 테스트
  • 이미지 크기를 필요한 만큼만 설정
  • 매일 무료 50 크레딧 활용

모델별 비용 비교

  • FLUX Schnell1 credit
  • FLUX Pro5 credits
  • Kling (5s video)20 credits
  • GPT-4o (1K tokens)~2 credits

7. 프롬프트 최적화

좋은 프롬프트는 더 나은 결과를 만듭니다. 모델별 프롬프트 작성 팁을 참고하세요.

이미지 생성 프롬프트

Vague Prompt

"a cat"

Detailed Prompt

"A fluffy orange tabby cat sitting on a windowsill, golden hour lighting, soft bokeh background, professional photography, 8K resolution"

프롬프트 구조

좋은 이미지 프롬프트는 다음 요소를 포함합니다:

  1. 주제 - 무엇을 그릴지 (subject)
  2. 스타일 - 어떤 스타일인지 (style)
  3. 조명 - 빛의 방향과 분위기 (lighting)
  4. 카메라 - 화각, 렌즈 (camera angle)
  5. 품질 - 해상도, 디테일 (quality)

비디오 생성 팁

  • -움직임을 명확히 설명하세요: "walking slowly", "camera panning left"
  • -시작 프레임이 중요합니다 - 이미지-to-비디오 시 좋은 이미지 사용
  • -복잡한 동작보다 단순하고 자연스러운 움직임이 더 잘 됩니다