SDK 및 클라이언트 라이브러리

OpenAI, Anthropic, Google SDK를 Atlas Cloud로 향하게 하는 방법과 이미지, 비디오, 오디오 생성을 위한 복사해서 바로 쓰는 Python·Node.js 클라이언트.

Atlas Cloud는 자체 SDK를 제공하지 않으며, 언어 모델이라면 애초에 필요하지도 않습니다 — API가 기존 SDK들이 이미 사용하는 형식을 그대로 받기 때문입니다. 미디어 생성의 경우, 프로젝트에 복사해 넣을 수 있는 작은 클라이언트를 이 페이지에 준비해 두었습니다.

호출 대상방법
언어 모델OpenAI, Anthropic 또는 Google SDK를 Atlas Cloud로 향하게 합니다
이미지, 비디오, 오디오, 3D비동기 엔드포인트에 대한 일반 HTTP 호출 — 클라이언트는 아래 참조
터미널이나 CI에서CLI
AI 지원 IDE에서MCP 서버

언어 모델

기본 URL과 API 키만 바꾸면 됩니다. 나머지는 그대로 둡니다.

pip install openai
import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["ATLASCLOUD_API_KEY"],
    base_url="https://api.atlascloud.ai/v1",
)

response = client.chat.completions.create(
    model="deepseek-ai/deepseek-v3.2",
    messages=[{"role": "user", "content": "Explain HTTP vs HTTPS"}],
)
print(response.choices[0].message.content)

모델마다 받아들이는 프로토콜이 다릅니다 — Messages만 지원하는 모델도, Responses만 지원하는 모델도 있습니다. Chat Completions가 당연히 된다고 가정하지 말고, 먼저 해당 모델의 API 레퍼런스를 확인하세요. LLM API 프로토콜을 참조하세요.

미디어 생성 클라이언트

이미지, 비디오, 오디오, 3D 생성은 비동기입니다. 작업을 제출한 뒤 폴링합니다. 다음은 필요한 것만 갖춘 최소 클라이언트입니다.

import os
import time
import requests

API_KEY = os.environ["ATLASCLOUD_API_KEY"]
BASE = "https://api.atlascloud.ai/api/v1"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}

# 엔드포인트는 출력 유형으로 결정된다: 3D는 image, 음성·음악·전사는 모두 audio
ENDPOINTS = {
    "image": f"{BASE}/model/generateImage",
    "video": f"{BASE}/model/generateVideo",
    "audio": f"{BASE}/model/generateAudio",
}
TERMINAL = {"completed", "succeeded", "failed", "timeout"}


def submit(kind: str, model: str, **params) -> str:
    """작업을 제출하고 prediction ID를 반환한다. 파라미터는 최상위에 두고 input으로 감싸지 않는다."""
    response = requests.post(
        ENDPOINTS[kind],
        headers=HEADERS,
        json={"model": model, **params},
        timeout=60,
    )
    response.raise_for_status()
    return response.json()["data"]["id"]


def wait(prediction_id: str, timeout: int = 600) -> dict:
    """종료 상태에 도달할 때까지 폴링한다. 간격을 점점 늘린다."""
    deadline = time.time() + timeout
    delay = 2.0

    while time.time() < deadline:
        response = requests.get(
            f"{BASE}/model/prediction/{prediction_id}",
            headers=HEADERS,
            timeout=30,
        )
        response.raise_for_status()
        data = response.json()["data"]

        if data.get("status") in TERMINAL:
            if data["status"] in ("failed", "timeout"):
                raise RuntimeError(f"생성 실패: {data.get('error') or data['status']}")
            return data

        time.sleep(delay)
        delay = min(delay * 1.5, 10.0)

    raise TimeoutError(f"작업 {prediction_id}이(가) {timeout}초 안에 끝나지 않았습니다")


def upload(path: str) -> str:
    """로컬 파일을 업로드하고 생성 요청에 쓸 수 있는 URL을 반환한다."""
    with open(path, "rb") as f:
        response = requests.post(
            f"{BASE}/model/uploadMedia", headers=HEADERS, files={"file": f}, timeout=600
        )
    response.raise_for_status()
    data = response.json()["data"]
    return data.get("download_url") or data.get("url")


if __name__ == "__main__":
    pid = submit("image", "MODEL_ID", prompt="a ceramic mug on a linen backdrop")
    result = wait(pid)
    print(result["outputs"][0])

이 클라이언트가 제대로 처리하고 있는, 틀리기 쉬운 두 가지:

  1. 파라미터는 최상위, model 과 같은 레벨에 둡니다 — input 객체로 감싸지 마세요.
  2. 전사 모델과 가사 모델에서는 outputs[0]이 URL이 아니라 텍스트입니다. 무턱대고 다운로드하지 마세요. 오디오 모델을 참조하세요.

프로덕션 참고 사항

  • 비디오에는 폴링보다 웹훅을 사용하세요. 비디오는 몇 분이 걸릴 수 있습니다. 웹훅을 참조하세요.
  • 429, 500, 503, 504는 지수 백오프로 재시도하세요. 400, 401, 402, 403은 재시도하지 마세요. 오류와 요청 제한을 참조하세요.
  • 제출 재시도는 신중하게 하세요. 제출이 타임아웃되어도 서버에서는 이미 접수되었을 수 있으며, 무작정 재시도하면 과금되는 작업이 하나 더 생깁니다. 비동기로 제출하고 폴링하세요.
  • 모든 응답의 X-Request-ID를 로그로 남기세요 — 지원팀이 호출을 추적할 때 필요한 값입니다.

커뮤니티 라이브러리

커뮤니티가 관리하는 래퍼는 awesome-atlas-cloud-integrations에 정리되어 있습니다. 독립적으로 관리되므로, 프로덕션에서 사용하기 전에 해당 래퍼가 실제로 무엇을 하는지 확인하세요.

관련 문서

Last updated on

On this page