Python SDK

Junyul Python SDK(junyul-kr)는 고객사의 AI 애플리케이션에 한 줄의 코드로 통합되어, 그 애플리케이션이 내리는 모든 의사결정·고지·이의제기·검토를 감사 가능한 이벤트로 자동 기록하는 계측 라이브러리입니다.

원본 데이터 비전송 원칙. SDK는 AI 추론의 입력·출력을 로컬에서 SHA-256으로 해시한 뒤 해시값만 Junyul 서버로 전송합니다. 원본은 고객 인프라를 벗어나지 않습니다.
릴리스 채널. 공개 PyPI 배포 전에는 도입 고객에게 제공되는 고객 전용 패키지 채널 또는 검증된 wheel/sdist로 설치합니다. 아래 명령은 공식 PyPI 또는 고객 registry가 연결된 환경 기준이며, 접근 권한은 support@junyul.com에서 확인합니다.

설치

# 공개 PyPI 릴리스 또는 고객 전용 패키지 채널 연결 후
pip install junyul-kr
  • Python: 3.10+
  • 의존성: httpx, pydantic v2, ulid-py. Optional extras: [image], [audio], [fastapi], [flask], [django].

초기화

import junyul
import os

junyul.init(
    api_key=os.environ["JUNYUL_API_KEY"],
    environment="production",
)

junyul.init()는 프로세스당 한 번만 호출합니다. 환경변수 JUNYUL_*로 설정을 오버라이드할 수 있습니다.

@junyul.track — 한 줄 통합

@junyul.track(asset_id="chatbot_v1")
def ask_ai(question: str) -> str:
    return openai.chat.completions.create(...)

데코레이터는 함수 입력을 SHA-256으로 해시한 input_hash와 결과를 해시한 output_hash를 담은 ai_inference 이벤트를 자동 기록합니다.

이벤트 모델 (SDK.md §3.3)

35종의 이벤트 타입을 6개 카테고리로 분류합니다. 각 카테고리에는 namespaced 헬퍼가 제공됩니다:

카테고리헬퍼이벤트 타입
Transparency (4)events.record_transparencynotice_shown, notice_dismissed, result_labeled, policy_disclosed
Decision (5)events.record_decisionautomated_decision_made, explanation_provided, human_review_triggered, human_review_completed, decision_reversed
Objection (4)events.record_objection_v2received, acknowledged, resolved, escalated
Assessment (4)events.record_assessmentimpact_assessment_started, impact_assessment_completed, impact_assessment_updated, risk_classification_changed
Model & Asset (6)events.record_model_lifecycle / record_assetmodel_deployed, model_retired, performance_degraded, asset.{created,updated,archived}
Incident (3) — EU Art. 73events.record_incidentdetected, reported_to_authority, mitigated

예: 자동화된 의사결정 기록 (PIPA §37조의2 + 신용정보법 §36조의2)

import junyul

junyul.events.record_decision(
    asset_id="credit_scoring_v3",
    action="automated_decision_made",
    legal_bases=["ai_basic_law_kr", "credit_info_36_2_kr", "pipa_37_2_kr"],
    risk_tier="high",
    subject_hash="sha256:...",
    outcome_hash="sha256:...",
    idempotency_key="credit_v3_req_abc123",  # → deterministic UUIDv5 event_id
)

예: 이의제기 접수 (PIPA §37조의2 ①)

junyul.events.record_objection_v2(
    asset_id="credit_scoring_v3",
    action="received",
    legal_bases=["pipa_37_2_kr", "credit_info_36_2_kr"],
    metadata={"original_decision_id": "dec_xyz", "reason_category": "bias_concern"},
)

예: 심각 사고 감지 (EU AI Act Article 73)

junyul.events.record_incident(
    asset_id="facial_recognition_v2",
    action="detected",
    legal_bases=["eu_ai_act_art_73"],
    metadata={"severity": "high", "detection_method": "canary_metric"},
)

legal_bases 전수 목록 (SDK.md §3.4)

  • ai_basic_law_kr — 한국 AI 기본법
  • pipa_37_2_kr — 개인정보보호법 §37조의2 (자동화된 의사결정)
  • credit_info_36_2_kr — 신용정보법 §36조의2 (자동화평가)
  • eu_ai_act, eu_ai_act_art_50, eu_ai_act_art_52, eu_ai_act_art_73 — EU AI Act
  • colorado_ai_act — Colorado AI Act (SB 24-205)
  • gdpr_art_22 — GDPR Article 22
  • nyc_local_law_144 — NYC Local Law 144 (AEDT)

risk_tier

  • low — 영향 미미
  • limited — EU AI Act Transparency 의무 수준
  • high — 고영향 AI / EU High-risk
  • prohibited — EU AI Act Article 5 금지 관행

신뢰성 프리미티브

junyul.Outbox

SQLite 기반 로컬 outbox. 네트워크 장애 시 이벤트를 durable하게 보관하고 복구 시 자동 전송합니다. 최대 100,000 rows, 7일 TTL.

junyul.CircuitBreaker

5회 연속 실패 시 OPEN으로 전환 → 30초 cooldown → HALF_OPEN에서 1회 시도 → 성공 시 CLOSED. Junyul 서버 장애가 고객 앱 응답 시간에 누적되지 않도록 합니다.

junyul.uuid7() / junyul.new_event_id()

시간 정렬 가능한 UUIDv7이 기본. idempotency_key를 전달하면 UUIDv5(namespace, key)로 결정적 event_id를 생성합니다. 재시도 시 서버가 중복 이벤트를 한 건으로 병합합니다.

프레임워크 통합

다음 단계