e14d303b82
config.py(Cafe24FtpConfig 일반화 + DESIGN_FILE_SPECS)·db.py(add/list_design_
revision)·router.py(design_files_router 연결)·_nav.html(탭 3개)·테스트·
.env.example·문서가 앞 커밋(8c2a9c4)에 함께 올라갔어야 하는데 스테이징 누락.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
109 lines
2.9 KiB
Python
109 lines
2.9 KiB
Python
"""카페24 연동 공통 계층 (상품관리 + 향후 주문관리 공유).
|
|
|
|
구성
|
|
config.py 환경변수 → Cafe24Config (하드코딩 금지)
|
|
crypto.py 토큰 Fernet 암복호화
|
|
oauth.py 인증 URL / code→token / refresh
|
|
tokens.py TokenService — 저장·만료판정·자동갱신(행 잠금)
|
|
client.py Cafe24Client — 전송·재시도·429/5xx·API 로그
|
|
products.py 상품 엔드포인트 래퍼
|
|
errors.py 공통 예외
|
|
|
|
사용 예 (모듈 라우터에서):
|
|
|
|
from app.integrations.cafe24 import build_cafe24_api
|
|
|
|
api = build_cafe24_api(store) # store = Cafe24Store
|
|
html = products.get_description(api.client, 123)
|
|
|
|
CAFE24_* 환경변수가 없어도 import 는 성공한다. 실제 호출 시점에
|
|
Cafe24ConfigError 가 나며, 라우터가 "설정 필요" 안내를 보여준다.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
from typing import Any
|
|
|
|
from . import design_ftp, products
|
|
from .client import Cafe24Client
|
|
from .config import (
|
|
DEFAULT_SCOPES,
|
|
DESIGN_FILE_SPECS,
|
|
DESIGN_SCOPES,
|
|
ORDER_SCOPES,
|
|
PRODUCT_SCOPES,
|
|
Cafe24Config,
|
|
Cafe24FtpConfig,
|
|
design_file_label,
|
|
design_file_path,
|
|
load_config,
|
|
load_ftp_config,
|
|
)
|
|
from .errors import (
|
|
Cafe24ApiError,
|
|
Cafe24AuthError,
|
|
Cafe24ConfigError,
|
|
Cafe24Error,
|
|
Cafe24FtpError,
|
|
Cafe24RateLimitError,
|
|
)
|
|
from .oauth import TokenBundle, build_authorize_url, exchange_code, new_state, refresh_tokens
|
|
from .tokens import TokenService
|
|
|
|
__all__ = [
|
|
"Cafe24Api",
|
|
"build_cafe24_api",
|
|
"Cafe24Client",
|
|
"Cafe24Config",
|
|
"Cafe24FtpConfig",
|
|
"load_ftp_config",
|
|
"design_ftp",
|
|
"DESIGN_FILE_SPECS",
|
|
"design_file_label",
|
|
"design_file_path",
|
|
"TokenService",
|
|
"TokenBundle",
|
|
"load_config",
|
|
"build_authorize_url",
|
|
"exchange_code",
|
|
"refresh_tokens",
|
|
"new_state",
|
|
"products",
|
|
"PRODUCT_SCOPES",
|
|
"ORDER_SCOPES",
|
|
"DESIGN_SCOPES",
|
|
"DEFAULT_SCOPES",
|
|
"Cafe24Error",
|
|
"Cafe24ConfigError",
|
|
"Cafe24AuthError",
|
|
"Cafe24RateLimitError",
|
|
"Cafe24ApiError",
|
|
"Cafe24FtpError",
|
|
]
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class Cafe24Api:
|
|
"""설정 + 토큰서비스 + 클라이언트 묶음. 라우터/worker 가 이것만 들고 다닌다."""
|
|
|
|
config: Cafe24Config
|
|
tokens: TokenService
|
|
client: Cafe24Client
|
|
|
|
|
|
def build_cafe24_api(store: Any, *, scopes: tuple[str, ...] = DEFAULT_SCOPES) -> Cafe24Api:
|
|
"""Cafe24Store 를 저장소로 쓰는 API 묶음 생성.
|
|
|
|
store 는 토큰 3개 메서드(get_token_row/save_token_row/token_lock)와
|
|
API 로그 기록용 log_api_call 을 제공해야 한다.
|
|
"""
|
|
config = load_config(scopes=scopes)
|
|
token_service = TokenService(store, config)
|
|
client = Cafe24Client(
|
|
config,
|
|
token_service,
|
|
api_logger=getattr(store, "log_api_call", None),
|
|
)
|
|
return Cafe24Api(config=config, tokens=token_service, client=client)
|