q_table_demo/app/main.py

131 lines
4.5 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

"""
FastAPI 메인 애플리케이션
"""
import uvicorn
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import HTMLResponse
from app.core.config import settings
from app.api.endpoints import router
# FastAPI 앱 생성
app = FastAPI(
title="Q-Table 협상 전략 데모 API",
description="기업 간 협상 시뮬레이션을 위한 강화학습 Q-Table 데모 API",
version="1.0.0",
docs_url="/docs",
redoc_url="/redoc"
)
# CORS 설정
app.add_middleware(
CORSMiddleware,
allow_origins=settings.allowed_origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# API 라우터 등록
app.include_router(router, prefix="/api/v1")
@app.get("/", response_class=HTMLResponse)
async def root():
"""루트 페이지"""
html_content = """
<!DOCTYPE html>
<html>
<head>
<title>Q-Table 협상 전략 데모 API</title>
<style>
body { font-family: Arial, sans-serif; margin: 40px; }
.header { color: #2c3e50; }
.section { margin: 20px 0; }
.link { color: #3498db; text-decoration: none; }
.link:hover { text-decoration: underline; }
.code { background-color: #f8f9fa; padding: 2px 4px; border-radius: 3px; }
</style>
</head>
<body>
<h1 class="header">🎯 Q-Table 협상 전략 데모 API</h1>
<div class="section">
<h2>📋 API 문서</h2>
<ul>
<li><a href="/docs" class="link">Swagger UI</a> - 대화형 API 문서</li>
<li><a href="/redoc" class="link">ReDoc</a> - 깔끔한 API 문서</li>
</ul>
</div>
<div class="section">
<h2>🚀 주요 기능</h2>
<ul>
<li><strong>보상 계산:</strong> <span class="code">POST /api/v1/reward/calculate</span></li>
<li><strong>에피소드 생성:</strong> <span class="code">POST /api/v1/episodes/generate</span></li>
<li><strong>Q-Learning 업데이트:</strong> <span class="code">POST /api/v1/learning/q-learning</span></li>
<li><strong>FQI+CQL 학습:</strong> <span class="code">POST /api/v1/learning/fqi-cql</span></li>
<li><strong>행동 추천:</strong> <span class="code">POST /api/v1/action/recommend</span></li>
<li><strong>시스템 상태:</strong> <span class="code">GET /api/v1/status</span></li>
</ul>
</div>
<div class="section">
<h2>📊 데이터 조회</h2>
<ul>
<li><strong>Q-Table:</strong> <span class="code">GET /api/v1/qtable</span></li>
<li><strong>경험 데이터:</strong> <span class="code">GET /api/v1/experiences</span></li>
<li><strong>FQI+CQL 결과:</strong> <span class="code">GET /api/v1/fqi-cql</span></li>
<li><strong>정책 비교:</strong> <span class="code">GET /api/v1/compare/{state}</span></li>
</ul>
</div>
<div class="section">
<h2>🔧 유틸리티</h2>
<ul>
<li><strong>헬스 체크:</strong> <span class="code">GET /api/v1/health</span></li>
<li><strong>시스템 초기화:</strong> <span class="code">POST /api/v1/reset</span></li>
<li><strong>설정 조회:</strong> <span class="code">GET /api/v1/config</span></li>
</ul>
</div>
<div class="section">
<h2>🎮 프론트엔드</h2>
<p>Streamlit 기반 대화형 인터페이스: <a href="http://localhost:8501" class="link">http://localhost:8501</a></p>
</div>
<div class="section">
<h2>📝 보상함수</h2>
<p><strong>R(s,a) = W × (A/P) + (1-W) × End</strong></p>
<ul>
<li><strong>W:</strong> 가중치 = (S_n + PZ_n) / 2</li>
<li><strong>A:</strong> 앵커링 목표가</li>
<li><strong>P:</strong> 상대방 제안가</li>
<li><strong>End:</strong> 협상 종료 여부</li>
</ul>
</div>
</body>
</html>
"""
return html_content
def start_api():
"""API 서버 시작 (Poetry 스크립트용)"""
uvicorn.run(
"app.main:app",
host=settings.api_host,
port=settings.api_port,
reload=True
)
if __name__ == "__main__":
uvicorn.run(
"app.main:app",
host=settings.api_host,
port=settings.api_port,
reload=True
)