Repository files navigation

🤖 TripTalk AI Server - FastAPI

Google Gemini 2.0 Flash 기반 맞춤형 여행 일정 생성 AI 서버

image

👥 팀 정보

📋 목차


🎯 프로젝트 개요

image

TripTalk AI Server는 사용자의 여행 스타일, 목적지, 예산, 동행인 정보를 기반으로 Google Gemini 2.0 Flash API를 활용하여 맞춤형 여행 일정을 자동 생성하는 FastAPI 기반 AI 서버입니다.

생성된 여행 계획은 JSON 파일로 임시 저장되며, 사용자 확인 후 Spring Boot 서버로 전송되어 MySQL DB에 영구 저장됩니다.

핵심 가치

  • 🤖 AI 맞춤 추천: Google Gemini 2.0 Flash 기반 개인화된 여행 일정 생성
  • 📅 상세 일정: 일별/시간대별 구체적인 여행 계획 (식당, 관광지, 교통편 포함)
  • 🏨 교통편/숙소 정보: 출발편, 귀환편, 숙소 예약 정보 자동 생성
  • 🔗 Spring Boot 연동: RESTful API 통신으로 완벽한 시스템 통합

✨ 주요 기능

1. 🗺️ AI 여행 일정 생성

  • Google Gemini 2.0 Flash API 연동

    • 사용자 입력 기반 프롬프트 생성
    • 자연어 기반 구조화된 JSON 응답
    • 9가지 여행 스타일 분석 (체험·액티비티, 자연과 함께, 여유롭게 힐링 등)
  • 상세 일정 생성

    • 일별 스케줄 (DailySchedule)
    • 시간대별 상세 계획 (ScheduleItem)
    • 실제 식당·관광지 이름 포함
    • 교통편 정보 (항공사명, 출발/도착 시간, 가격)
    • 숙소 정보 (호텔명, 주소, 1박 가격)
  • 하이라이트 추출

    • 여행의 주요 포인트 3-5개 자동 생성
    • 각 하이라이트 100자 이내
image

2. 📋 여행 계획 관리

  • JSON 파일 기반 저장

    • data/travel_data.json에 영구 저장
    • UUID 기반 고유 ID 생성
    • 중복 방지 로직 (동일 조건 시 업데이트)
  • 여행 목록 조회

    • 전체 여행 목록 반환
    • 특정 여행 상세 조회
image

3. 🔗 Spring Boot 연동

  • HTTP POST 통신

    • FastAPI → Spring Boot REST API 호출
    • JSON 데이터 자동 직렬화 (camelCase 변환)
    • 에러 핸들링 및 재시도 로직
  • 데이터 변환

    • Pydantic 모델 → JSON (by_alias=True)
    • snake_case → camelCase 자동 변환
    • Spring Boot DTO 형식에 맞춘 데이터 구조

🛠 기술 스택

Backend

  • Language: Python 3.11+
  • Framework: FastAPI 0.115.5
  • AI: Google Gemini 2.0 Flash API
  • Data Validation: Pydantic 2.10.3
  • HTTP Client: httpx 0.28.1
  • CORS: FastAPI CORS Middleware

Storage

  • File System: JSON 파일 기반 데이터 저장
  • Data Format: UTF-8 JSON (ensure_ascii=False)

External APIs

  • Google Gemini API: Gemini 2.0 Flash 기반 여행 일정 생성
  • Spring Boot API: 여행 계획 DB 저장

🏗 시스템 아키텍처

┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ Client │ ───> │ FastAPI │ ───> │ Google │
│ (Mobile) │ │ (AI Server) │ │ Gemini 2.0 │
└─────────────┘ └──────────────┘ └─────────────┘
│
├──────> Spring Boot API
│ (DB 저장)
│
└──────> data/travel_data.json
(임시 저장)

데이터 플로우

1. 사용자 입력 (목적지, 기간, 예산, 동행인, 여행 스타일)
↓
2. FastAPI → Google Gemini 2.0 Flash API 요청
↓
3. Gemini → 구조화된 여행 계획 JSON 생성
↓
4. FastAPI → Pydantic 모델 검증 및 저장 (travel_data.json)
↓
5. 사용자 확인 후 "저장" 버튼 클릭
↓
6. FastAPI → Spring Boot API 호출 (POST /api/trip-plan/from-fastapi)
↓
7. Spring Boot → MySQL DB 저장

📦 데이터 모델

Pydantic 모델 구조

TravelStyle (여행 스타일)

classTravelStyle(BaseModel):
category: str# "체험·액티비티", "자연과 함께", "여유롭게 힐링" 등

ScheduleItem (상세 일정)

classScheduleItem(BaseModel):
order_index: int# 순서time: str# "09:00"title: str# "김포공항 출발"description: str# "진에어 LJ313편으로 제주 출발"

DailySchedule (일별 일정)

classDailySchedule(BaseModel):
day: int# 1, 2, 3...date: str# "2025-12-13"schedules: List[ScheduleItem] # 상세 일정 리스트

TripTransportation (교통편)

classTripTransportation(BaseModel):
origin: str# "김포공항"destination: str# "제주공항"name: str# "진에어LJ313"price: int# 45000

TripAccommodation (숙소)

classTripAccommodation(BaseModel):
name: str# "제주신화월드 호텔"address: str# "제주 서귀포시..."pricePerNight: int# 200000

TripPlan (전체 여행 계획)

classTripPlan(BaseModel):
title: str# "제주도 2박 3일 우정 여행"destination: str# "제주도"departure: str# "서울"startDate: str (alias='start_date') # "2025-12-13"endDate: str (alias='end_date') # "2025-12-15"companions: str# "친구"budget: str# "70만원"travelStyles: List[TravelStyle] # 여행 스타일 리스트highlights: List[TripHighlight] # 하이라이트 리스트fullPlan: str (alias='full_plan') # 전체 텍스트 계획dailySchedules: List[DailySchedule] # 일별 일정outboundTransportation: TripTransportation# 출발 교통편returnTransportation: TripTransportation# 귀환 교통편accommodations: List[TripAccommodation] # 숙소 리스트

📡 API 명세

Base URL

Production: http://52.78.55.147:8000
Local Development: http://localhost:8000

1. 여행 계획 생성

여행 계획 생성 요청

POST /Travel-PlanContent-Type: application/json
{
"companions": "친구",
"departure": "서울",
"destination": "제주도",
"start_date": "2025-12-13",
"end_date": "2025-12-15",
"style": ["자연과 함께", "여유롭게 힐링"],
"budget": "50만원~70만원"
}

응답 예시:

{
"travel_id": "37488429-3759-4320-9603-a0db0277bd56",
"title": "제주도 2박 3일 우정 여행",
"destination": "제주도",
"departure": "서울",
"start_date": "2025-12-13",
"end_date": "2025-12-15",
"companions": "친구",
"budget": "70만원",
"travel_styles": [
{"category": "자연과 함께"}
],
"highlights": [
{"content": "겨울 바다 만끽하며 우정 스냅 촬영"},
{"content": "따뜻한 온천으로 피로 풀기"},
{"content": "제주 흑돼지 맛집 탐방"}
],
"daily_schedules": [
{
"day": 1,
"date": "2025-12-13",
"schedules": [
{
"order_index": 1,
"time": "07:30",
"title": "비행기 탑승",
"description": "김포공항에서 진에어 LJ313편으로 제주로 출발"
}
]
}
],
"outbound_transportation": {
"origin": "김포공항",
"destination": "제주공항",
"name": "진에어LJ313",
"price": 45000
},
"return_transportation": {...},
"accommodations": [...]
}

2. 여행 목록 조회

전체 여행 목록

GET /travel-summaries

특정 여행 상세 조회

GET /travel-summary/{travel_id}

3. Spring Boot 연동

여행 계획 저장 (Spring Boot로 전송)

POST /save-plan/{travel_id}Response:
{
"success": true,
"message": "여행 계획이 Spring Boot 서버에 성공적으로 저장되었습니다.",
"spring_response": {
"id": 123,
"title": "제주도 2박 3일 우정 여행",
...
},
"fastapi_travel_id": "37488429-3759-4320-9603-a0db0277bd56"
}

🚀 설치 및 실행

배포 환경

현재 AWS EC2 (52.78.55.147)에 Docker Compose로 배포 운영 중입니다.

서버 정보

Docker Compose로 실행

# 서버에서 실행cd /path/to/TripTalk
docker-compose up -d
# 로그 확인
docker-compose logs -f fastapi
# 재시작
docker-compose restart fastapi
# 중지
docker-compose down

환경변수 설정

.env 파일:

# Google Gemini API Key
GOOGLE_API_KEY=your-google-gemini-api-key-here
# Spring Boot Server URL (배포 환경)
SPRING_BOOT_URL=http://52.78.55.147:8080

로컬 개발 환경 (선택사항)

요구사항

  • Python 3.11 이상
  • Google Gemini API Key

1. 가상환경 생성 및 활성화

# 가상환경 생성
python3 -m venv venv
# 활성화 (macOS/Linux)source venv/bin/activate

2. 패키지 설치

pip install -r requirements.txt

requirements.txt:

fastapi==0.115.5
uvicorn==0.34.0
pydantic==2.10.3
google-generativeai==0.8.3
httpx==0.28.1
python-dotenv==1.0.1

3. 환경변수 설정 (로컬)

.env 파일:

GOOGLE_API_KEY=your-api-key
SPRING_BOOT_URL=http://localhost:8080

4. 로컬 실행

# 개발 모드
uvicorn AI_Chat:app --reload --host 0.0.0.0 --port 8000

5. API 테스트

# 배포 서버 테스트
curl http://52.78.55.147:8000/travel-summaries
# 로컬 테스트
curl http://localhost:8000/travel-summaries

🐳 배포 환경 (Docker)

현재 배포 상태

Docker Compose로 운영 중이며, docker-compose.yml 설정:

version: "3.9"services:
fastapi:
build: .container_name: fastapi-serverports:
- "8000:8000"restart: alwaysenvironment:
GOOGLE_API_KEY: ${GOOGLE_API_KEY}SPRING_BOOT_URL: http://52.78.55.147:8080volumes:
- ./data:/app/data
- ./outputs:/app/outputs

Dockerfile

FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["uvicorn", "AI_Chat:app", "--host", "0.0.0.0", "--port", "8000"]

배포 관리 명령어

# 서버 배포 (처음 또는 코드 변경 시)
docker-compose up -d --build
# 서버 재시작
docker-compose restart
# 로그 확인
docker-compose logs -f fastapi
# 서버 중지
docker-compose down
# 컨테이너 상태 확인
docker-compose ps

🔗 Spring Boot 연동

연동 플로우

1. FastAPI에서 여행 계획 생성 → travel_data.json 저장
2. 사용자 확인 후 "저장" 버튼 클릭
3. FastAPI → Spring Boot API 호출
POST http://52.78.55.147:8080/api/trip-plan/from-fastapi
4. Spring Boot → MySQL DB 저장
5. 저장 결과 반환

데이터 변환 과정

FastAPI (snake_case) → Spring Boot (camelCase)

# TripPlan 모델 (FastAPI)plan_data=plan_response.model_dump(by_alias=True)
# startDate, endDate, dailySchedules... (camelCase)# Spring Boot로 전송 (배포 환경)asyncwithhttpx.AsyncClient() asclient:
response=awaitclient.post(
"http://52.78.55.147:8080/api/trip-plan/from-fastapi",
json=plan_data
)

Spring Boot CreateFromFastAPIDTO:

publicstaticclassCreateFromFastAPIDTO {
privateStringstartDate; // FastAPI에서 "startDate" 전송privateStringendDate;
privateStringbudget;
privateList<DailyScheduleDTO> dailySchedules;
// ...
}

배포 환경 구성

┌─────────────────┐
│ Client App │
│ (Mobile/Web) │
└────────┬────────┘
│
├──────────────────────┬─────────────────────┐
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ FastAPI Server │ │ Spring Boot API │ │ Google │
│ (Docker) │─>│ (AWS EC2) │ │ Gemini API │
│ Port: 8000 │ │ 52.78.55.147 │ └─────────────────┘
└─────────────────┘ └────────┬─────────┘
│ │
▼ ▼
┌─────────────────┐ ┌──────────────────┐
│ travel_data.json│ │ MySQL (RDS) │
│ (로컬 저장) │ │ (영구 저장) │
└─────────────────┘ └──────────────────┘

📂 프로젝트 구조

TripTalk/
├── AI_Chat.py # 메인 FastAPI 애플리케이션
├── main.py # 애플리케이션 엔트리 포인트
├── requirements.txt # Python 패키지 의존성
├── .env # 환경변수 (OpenAI API Key)
├── Dockerfile # Docker 이미지 빌드 파일
├── docker-compose.yml # Docker Compose 설정
├── README.md # 프로젝트 문서
├── data/
│ └── travel_data.json # 여행 계획 JSON 저장소
└── outputs/
└── latest_plan.md # 최신 여행 계획 마크다운

🔧 주요 기술적 특징

1. Pydantic Field Aliases

  • JSON 파일: start_date, end_date (snake_case)
  • Python 모델: startDate, endDate (camelCase)
  • Spring Boot 전송: startDate, endDate (camelCase)
classTripPlan(BaseModel):
startDate: str=Field(..., alias='start_date')
endDate: str=Field(..., alias='end_date')

2. Google Gemini Structured Output

  • Gemini 2.0 Flash의 자연어 기반 JSON 생성
  • Pydantic 모델과 일치하는 구조화된 응답
  • 파싱 에러 최소화

3. 중복 방지 로직

  • 동일 조건 (목적지, 기간, 동행자, 예산, 스타일) 시 기존 데이터 업데이트
  • 다른 조건 시 새 UUID 생성

4. 에러 핸들링

  • Spring Boot 통신 실패 시 재시도
  • Google Gemini API 타임아웃 처리
  • JSON 파싱 에러 복구

📝 커밋 메시지 규칙

타입(Type)설명(Description)
Feat새로운 기능을 추가한 경우
Fix에러·버그를 수정한 경우
DesignCSS 등 UI 디자인을 변경한 경우
HOTFIX급하게 치명적인 에러를 즉시 수정한 경우
Style코드 포맷 변경, 세미콜론 누락 등 로직 변경 없는 스타일 수정
Refactor기능 변화 없이 코드를 리팩토링한 경우
Comment주석 추가 또는 변경
Docs문서를 수정한 경우 (README 등)
Test테스트 코드 추가·변경·리팩토링
Chore기타 변경사항 (빌드, 패키지, 설정 파일 수정 등)
Rename파일·폴더명을 수정하거나 옮기는 경우

예시

git commit -m "Feat: Google Gemini 2.0 Flash 여행 계획 생성 API 추가"
git commit -m "Fix: Spring Boot 연동 시 camelCase 변환 오류 수정"
git commit -m "Docs: README 데이터 모델 섹션 추가"

🔄 버전 히스토리

v1.0.0 (2025-12-12)

  • ✅ Google Gemini 2.0 Flash 기반 여행 계획 생성
  • ✅ Pydantic 모델 기반 데이터 검증
  • ✅ JSON 파일 기반 영구 저장
  • ✅ Spring Boot API 연동 완료
  • ✅ camelCase/snake_case 자동 변환

🤖 TripTalk AI Server - 당신만의 완벽한 여행을 AI가 설계합니다!

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

🤖 TripTalk AI Server - FastAPI

Google Gemini 2.0 Flash 기반 맞춤형 여행 일정 생성 AI 서버

image

👥 팀 정보

📋 목차


🎯 프로젝트 개요

image

TripTalk AI Server는 사용자의 여행 스타일, 목적지, 예산, 동행인 정보를 기반으로 Google Gemini 2.0 Flash API를 활용하여 맞춤형 여행 일정을 자동 생성하는 FastAPI 기반 AI 서버입니다.

생성된 여행 계획은 JSON 파일로 임시 저장되며, 사용자 확인 후 Spring Boot 서버로 전송되어 MySQL DB에 영구 저장됩니다.

핵심 가치

  • 🤖 AI 맞춤 추천: Google Gemini 2.0 Flash 기반 개인화된 여행 일정 생성
  • 📅 상세 일정: 일별/시간대별 구체적인 여행 계획 (식당, 관광지, 교통편 포함)
  • 🏨 교통편/숙소 정보: 출발편, 귀환편, 숙소 예약 정보 자동 생성
  • 🔗 Spring Boot 연동: RESTful API 통신으로 완벽한 시스템 통합

✨ 주요 기능

1. 🗺️ AI 여행 일정 생성

  • Google Gemini 2.0 Flash API 연동

    • 사용자 입력 기반 프롬프트 생성
    • 자연어 기반 구조화된 JSON 응답
    • 9가지 여행 스타일 분석 (체험·액티비티, 자연과 함께, 여유롭게 힐링 등)
  • 상세 일정 생성

    • 일별 스케줄 (DailySchedule)
    • 시간대별 상세 계획 (ScheduleItem)
    • 실제 식당·관광지 이름 포함
    • 교통편 정보 (항공사명, 출발/도착 시간, 가격)
    • 숙소 정보 (호텔명, 주소, 1박 가격)
  • 하이라이트 추출

    • 여행의 주요 포인트 3-5개 자동 생성
    • 각 하이라이트 100자 이내
image

2. 📋 여행 계획 관리

  • JSON 파일 기반 저장

    • data/travel_data.json에 영구 저장
    • UUID 기반 고유 ID 생성
    • 중복 방지 로직 (동일 조건 시 업데이트)
  • 여행 목록 조회

    • 전체 여행 목록 반환
    • 특정 여행 상세 조회
image

3. 🔗 Spring Boot 연동

  • HTTP POST 통신

    • FastAPI → Spring Boot REST API 호출
    • JSON 데이터 자동 직렬화 (camelCase 변환)
    • 에러 핸들링 및 재시도 로직
  • 데이터 변환

    • Pydantic 모델 → JSON (by_alias=True)
    • snake_case → camelCase 자동 변환
    • Spring Boot DTO 형식에 맞춘 데이터 구조

🛠 기술 스택

Backend

  • Language: Python 3.11+
  • Framework: FastAPI 0.115.5
  • AI: Google Gemini 2.0 Flash API
  • Data Validation: Pydantic 2.10.3
  • HTTP Client: httpx 0.28.1
  • CORS: FastAPI CORS Middleware

Storage

  • File System: JSON 파일 기반 데이터 저장
  • Data Format: UTF-8 JSON (ensure_ascii=False)

External APIs

  • Google Gemini API: Gemini 2.0 Flash 기반 여행 일정 생성
  • Spring Boot API: 여행 계획 DB 저장

🏗 시스템 아키텍처

┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ Client │ ───> │ FastAPI │ ───> │ Google │
│ (Mobile) │ │ (AI Server) │ │ Gemini 2.0 │
└─────────────┘ └──────────────┘ └─────────────┘
│
├──────> Spring Boot API
│ (DB 저장)
│
└──────> data/travel_data.json
(임시 저장)

데이터 플로우

1. 사용자 입력 (목적지, 기간, 예산, 동행인, 여행 스타일)
↓
2. FastAPI → Google Gemini 2.0 Flash API 요청
↓
3. Gemini → 구조화된 여행 계획 JSON 생성
↓
4. FastAPI → Pydantic 모델 검증 및 저장 (travel_data.json)
↓
5. 사용자 확인 후 "저장" 버튼 클릭
↓
6. FastAPI → Spring Boot API 호출 (POST /api/trip-plan/from-fastapi)
↓
7. Spring Boot → MySQL DB 저장

📦 데이터 모델

Pydantic 모델 구조

TravelStyle (여행 스타일)

classTravelStyle(BaseModel):
category: str# "체험·액티비티", "자연과 함께", "여유롭게 힐링" 등

ScheduleItem (상세 일정)

classScheduleItem(BaseModel):
order_index: int# 순서time: str# "09:00"title: str# "김포공항 출발"description: str# "진에어 LJ313편으로 제주 출발"

DailySchedule (일별 일정)

classDailySchedule(BaseModel):
day: int# 1, 2, 3...date: str# "2025-12-13"schedules: List[ScheduleItem] # 상세 일정 리스트

TripTransportation (교통편)

classTripTransportation(BaseModel):
origin: str# "김포공항"destination: str# "제주공항"name: str# "진에어LJ313"price: int# 45000

TripAccommodation (숙소)

classTripAccommodation(BaseModel):
name: str# "제주신화월드 호텔"address: str# "제주 서귀포시..."pricePerNight: int# 200000

TripPlan (전체 여행 계획)

classTripPlan(BaseModel):
title: str# "제주도 2박 3일 우정 여행"destination: str# "제주도"departure: str# "서울"startDate: str (alias='start_date') # "2025-12-13"endDate: str (alias='end_date') # "2025-12-15"companions: str# "친구"budget: str# "70만원"travelStyles: List[TravelStyle] # 여행 스타일 리스트highlights: List[TripHighlight] # 하이라이트 리스트fullPlan: str (alias='full_plan') # 전체 텍스트 계획dailySchedules: List[DailySchedule] # 일별 일정outboundTransportation: TripTransportation# 출발 교통편returnTransportation: TripTransportation# 귀환 교통편accommodations: List[TripAccommodation] # 숙소 리스트

📡 API 명세

Base URL

Production: http://52.78.55.147:8000
Local Development: http://localhost:8000

1. 여행 계획 생성

여행 계획 생성 요청

POST /Travel-PlanContent-Type: application/json
{
"companions": "친구",
"departure": "서울",
"destination": "제주도",
"start_date": "2025-12-13",
"end_date": "2025-12-15",
"style": ["자연과 함께", "여유롭게 힐링"],
"budget": "50만원~70만원"
}

응답 예시:

{
"travel_id": "37488429-3759-4320-9603-a0db0277bd56",
"title": "제주도 2박 3일 우정 여행",
"destination": "제주도",
"departure": "서울",
"start_date": "2025-12-13",
"end_date": "2025-12-15",
"companions": "친구",
"budget": "70만원",
"travel_styles": [
{"category": "자연과 함께"}
],
"highlights": [
{"content": "겨울 바다 만끽하며 우정 스냅 촬영"},
{"content": "따뜻한 온천으로 피로 풀기"},
{"content": "제주 흑돼지 맛집 탐방"}
],
"daily_schedules": [
{
"day": 1,
"date": "2025-12-13",
"schedules": [
{
"order_index": 1,
"time": "07:30",
"title": "비행기 탑승",
"description": "김포공항에서 진에어 LJ313편으로 제주로 출발"
}
]
}
],
"outbound_transportation": {
"origin": "김포공항",
"destination": "제주공항",
"name": "진에어LJ313",
"price": 45000
},
"return_transportation": {...},
"accommodations": [...]
}

2. 여행 목록 조회

전체 여행 목록

GET /travel-summaries

특정 여행 상세 조회

GET /travel-summary/{travel_id}

3. Spring Boot 연동

여행 계획 저장 (Spring Boot로 전송)

POST /save-plan/{travel_id}Response:
{
"success": true,
"message": "여행 계획이 Spring Boot 서버에 성공적으로 저장되었습니다.",
"spring_response": {
"id": 123,
"title": "제주도 2박 3일 우정 여행",
...
},
"fastapi_travel_id": "37488429-3759-4320-9603-a0db0277bd56"
}

🚀 설치 및 실행

배포 환경

현재 AWS EC2 (52.78.55.147)에 Docker Compose로 배포 운영 중입니다.

서버 정보

Docker Compose로 실행

# 서버에서 실행cd /path/to/TripTalk
docker-compose up -d
# 로그 확인
docker-compose logs -f fastapi
# 재시작
docker-compose restart fastapi
# 중지
docker-compose down

환경변수 설정

.env 파일:

# Google Gemini API Key
GOOGLE_API_KEY=your-google-gemini-api-key-here
# Spring Boot Server URL (배포 환경)
SPRING_BOOT_URL=http://52.78.55.147:8080

로컬 개발 환경 (선택사항)

요구사항

  • Python 3.11 이상
  • Google Gemini API Key

1. 가상환경 생성 및 활성화

# 가상환경 생성
python3 -m venv venv
# 활성화 (macOS/Linux)source venv/bin/activate

2. 패키지 설치

pip install -r requirements.txt

requirements.txt:

fastapi==0.115.5
uvicorn==0.34.0
pydantic==2.10.3
google-generativeai==0.8.3
httpx==0.28.1
python-dotenv==1.0.1

3. 환경변수 설정 (로컬)

.env 파일:

GOOGLE_API_KEY=your-api-key
SPRING_BOOT_URL=http://localhost:8080

4. 로컬 실행

# 개발 모드
uvicorn AI_Chat:app --reload --host 0.0.0.0 --port 8000

5. API 테스트

# 배포 서버 테스트
curl http://52.78.55.147:8000/travel-summaries
# 로컬 테스트
curl http://localhost:8000/travel-summaries

🐳 배포 환경 (Docker)

현재 배포 상태

Docker Compose로 운영 중이며, docker-compose.yml 설정:

version: "3.9"services:
fastapi:
build: .container_name: fastapi-serverports:
- "8000:8000"restart: alwaysenvironment:
GOOGLE_API_KEY: ${GOOGLE_API_KEY}SPRING_BOOT_URL: http://52.78.55.147:8080volumes:
- ./data:/app/data
- ./outputs:/app/outputs

Dockerfile

FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["uvicorn", "AI_Chat:app", "--host", "0.0.0.0", "--port", "8000"]

배포 관리 명령어

# 서버 배포 (처음 또는 코드 변경 시)
docker-compose up -d --build
# 서버 재시작
docker-compose restart
# 로그 확인
docker-compose logs -f fastapi
# 서버 중지
docker-compose down
# 컨테이너 상태 확인
docker-compose ps

🔗 Spring Boot 연동

연동 플로우

1. FastAPI에서 여행 계획 생성 → travel_data.json 저장
2. 사용자 확인 후 "저장" 버튼 클릭
3. FastAPI → Spring Boot API 호출
POST http://52.78.55.147:8080/api/trip-plan/from-fastapi
4. Spring Boot → MySQL DB 저장
5. 저장 결과 반환

데이터 변환 과정

FastAPI (snake_case) → Spring Boot (camelCase)

# TripPlan 모델 (FastAPI)plan_data=plan_response.model_dump(by_alias=True)
# startDate, endDate, dailySchedules... (camelCase)# Spring Boot로 전송 (배포 환경)asyncwithhttpx.AsyncClient() asclient:
response=awaitclient.post(
"http://52.78.55.147:8080/api/trip-plan/from-fastapi",
json=plan_data
)

Spring Boot CreateFromFastAPIDTO:

publicstaticclassCreateFromFastAPIDTO {
privateStringstartDate; // FastAPI에서 "startDate" 전송privateStringendDate;
privateStringbudget;
privateList<DailyScheduleDTO> dailySchedules;
// ...
}

배포 환경 구성

┌─────────────────┐
│ Client App │
│ (Mobile/Web) │
└────────┬────────┘
│
├──────────────────────┬─────────────────────┐
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ FastAPI Server │ │ Spring Boot API │ │ Google │
│ (Docker) │─>│ (AWS EC2) │ │ Gemini API │
│ Port: 8000 │ │ 52.78.55.147 │ └─────────────────┘
└─────────────────┘ └────────┬─────────┘
│ │
▼ ▼
┌─────────────────┐ ┌──────────────────┐
│ travel_data.json│ │ MySQL (RDS) │
│ (로컬 저장) │ │ (영구 저장) │
└─────────────────┘ └──────────────────┘

📂 프로젝트 구조

TripTalk/
├── AI_Chat.py # 메인 FastAPI 애플리케이션
├── main.py # 애플리케이션 엔트리 포인트
├── requirements.txt # Python 패키지 의존성
├── .env # 환경변수 (OpenAI API Key)
├── Dockerfile # Docker 이미지 빌드 파일
├── docker-compose.yml # Docker Compose 설정
├── README.md # 프로젝트 문서
├── data/
│ └── travel_data.json # 여행 계획 JSON 저장소
└── outputs/
└── latest_plan.md # 최신 여행 계획 마크다운

🔧 주요 기술적 특징

1. Pydantic Field Aliases

  • JSON 파일: start_date, end_date (snake_case)
  • Python 모델: startDate, endDate (camelCase)
  • Spring Boot 전송: startDate, endDate (camelCase)
classTripPlan(BaseModel):
startDate: str=Field(..., alias='start_date')
endDate: str=Field(..., alias='end_date')

2. Google Gemini Structured Output

  • Gemini 2.0 Flash의 자연어 기반 JSON 생성
  • Pydantic 모델과 일치하는 구조화된 응답
  • 파싱 에러 최소화

3. 중복 방지 로직

  • 동일 조건 (목적지, 기간, 동행자, 예산, 스타일) 시 기존 데이터 업데이트
  • 다른 조건 시 새 UUID 생성

4. 에러 핸들링

  • Spring Boot 통신 실패 시 재시도
  • Google Gemini API 타임아웃 처리
  • JSON 파싱 에러 복구

📝 커밋 메시지 규칙

타입(Type)설명(Description)
Feat새로운 기능을 추가한 경우
Fix에러·버그를 수정한 경우
DesignCSS 등 UI 디자인을 변경한 경우
HOTFIX급하게 치명적인 에러를 즉시 수정한 경우
Style코드 포맷 변경, 세미콜론 누락 등 로직 변경 없는 스타일 수정
Refactor기능 변화 없이 코드를 리팩토링한 경우
Comment주석 추가 또는 변경
Docs문서를 수정한 경우 (README 등)
Test테스트 코드 추가·변경·리팩토링
Chore기타 변경사항 (빌드, 패키지, 설정 파일 수정 등)
Rename파일·폴더명을 수정하거나 옮기는 경우

예시

git commit -m "Feat: Google Gemini 2.0 Flash 여행 계획 생성 API 추가"
git commit -m "Fix: Spring Boot 연동 시 camelCase 변환 오류 수정"
git commit -m "Docs: README 데이터 모델 섹션 추가"

🔄 버전 히스토리

v1.0.0 (2025-12-12)

  • ✅ Google Gemini 2.0 Flash 기반 여행 계획 생성
  • ✅ Pydantic 모델 기반 데이터 검증
  • ✅ JSON 파일 기반 영구 저장
  • ✅ Spring Boot API 연동 완료
  • ✅ camelCase/snake_case 자동 변환

🤖 TripTalk AI Server - 당신만의 완벽한 여행을 AI가 설계합니다!

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

🤖 TripTalk AI Server - FastAPI

Google Gemini 2.0 Flash 기반 맞춤형 여행 일정 생성 AI 서버

image

👥 팀 정보

📋 목차


🎯 프로젝트 개요

image

TripTalk AI Server는 사용자의 여행 스타일, 목적지, 예산, 동행인 정보를 기반으로 Google Gemini 2.0 Flash API를 활용하여 맞춤형 여행 일정을 자동 생성하는 FastAPI 기반 AI 서버입니다.

생성된 여행 계획은 JSON 파일로 임시 저장되며, 사용자 확인 후 Spring Boot 서버로 전송되어 MySQL DB에 영구 저장됩니다.

핵심 가치

  • 🤖 AI 맞춤 추천: Google Gemini 2.0 Flash 기반 개인화된 여행 일정 생성
  • 📅 상세 일정: 일별/시간대별 구체적인 여행 계획 (식당, 관광지, 교통편 포함)
  • 🏨 교통편/숙소 정보: 출발편, 귀환편, 숙소 예약 정보 자동 생성
  • 🔗 Spring Boot 연동: RESTful API 통신으로 완벽한 시스템 통합

✨ 주요 기능

1. 🗺️ AI 여행 일정 생성

  • Google Gemini 2.0 Flash API 연동

    • 사용자 입력 기반 프롬프트 생성
    • 자연어 기반 구조화된 JSON 응답
    • 9가지 여행 스타일 분석 (체험·액티비티, 자연과 함께, 여유롭게 힐링 등)
  • 상세 일정 생성

    • 일별 스케줄 (DailySchedule)
    • 시간대별 상세 계획 (ScheduleItem)
    • 실제 식당·관광지 이름 포함
    • 교통편 정보 (항공사명, 출발/도착 시간, 가격)
    • 숙소 정보 (호텔명, 주소, 1박 가격)
  • 하이라이트 추출

    • 여행의 주요 포인트 3-5개 자동 생성
    • 각 하이라이트 100자 이내
image

2. 📋 여행 계획 관리

  • JSON 파일 기반 저장

    • data/travel_data.json에 영구 저장
    • UUID 기반 고유 ID 생성
    • 중복 방지 로직 (동일 조건 시 업데이트)
  • 여행 목록 조회

    • 전체 여행 목록 반환
    • 특정 여행 상세 조회
image

3. 🔗 Spring Boot 연동

  • HTTP POST 통신

    • FastAPI → Spring Boot REST API 호출
    • JSON 데이터 자동 직렬화 (camelCase 변환)
    • 에러 핸들링 및 재시도 로직
  • 데이터 변환

    • Pydantic 모델 → JSON (by_alias=True)
    • snake_case → camelCase 자동 변환
    • Spring Boot DTO 형식에 맞춘 데이터 구조

🛠 기술 스택

Backend

  • Language: Python 3.11+
  • Framework: FastAPI 0.115.5
  • AI: Google Gemini 2.0 Flash API
  • Data Validation: Pydantic 2.10.3
  • HTTP Client: httpx 0.28.1
  • CORS: FastAPI CORS Middleware

Storage

  • File System: JSON 파일 기반 데이터 저장
  • Data Format: UTF-8 JSON (ensure_ascii=False)

External APIs

  • Google Gemini API: Gemini 2.0 Flash 기반 여행 일정 생성
  • Spring Boot API: 여행 계획 DB 저장

🏗 시스템 아키텍처

┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ Client │ ───> │ FastAPI │ ───> │ Google │
│ (Mobile) │ │ (AI Server) │ │ Gemini 2.0 │
└─────────────┘ └──────────────┘ └─────────────┘
│
├──────> Spring Boot API
│ (DB 저장)
│
└──────> data/travel_data.json
(임시 저장)

데이터 플로우

1. 사용자 입력 (목적지, 기간, 예산, 동행인, 여행 스타일)
↓
2. FastAPI → Google Gemini 2.0 Flash API 요청
↓
3. Gemini → 구조화된 여행 계획 JSON 생성
↓
4. FastAPI → Pydantic 모델 검증 및 저장 (travel_data.json)
↓
5. 사용자 확인 후 "저장" 버튼 클릭
↓
6. FastAPI → Spring Boot API 호출 (POST /api/trip-plan/from-fastapi)
↓
7. Spring Boot → MySQL DB 저장

📦 데이터 모델

Pydantic 모델 구조

TravelStyle (여행 스타일)

classTravelStyle(BaseModel):
category: str# "체험·액티비티", "자연과 함께", "여유롭게 힐링" 등

ScheduleItem (상세 일정)

classScheduleItem(BaseModel):
order_index: int# 순서time: str# "09:00"title: str# "김포공항 출발"description: str# "진에어 LJ313편으로 제주 출발"

DailySchedule (일별 일정)

classDailySchedule(BaseModel):
day: int# 1, 2, 3...date: str# "2025-12-13"schedules: List[ScheduleItem] # 상세 일정 리스트

TripTransportation (교통편)

classTripTransportation(BaseModel):
origin: str# "김포공항"destination: str# "제주공항"name: str# "진에어LJ313"price: int# 45000

TripAccommodation (숙소)

classTripAccommodation(BaseModel):
name: str# "제주신화월드 호텔"address: str# "제주 서귀포시..."pricePerNight: int# 200000

TripPlan (전체 여행 계획)

classTripPlan(BaseModel):
title: str# "제주도 2박 3일 우정 여행"destination: str# "제주도"departure: str# "서울"startDate: str (alias='start_date') # "2025-12-13"endDate: str (alias='end_date') # "2025-12-15"companions: str# "친구"budget: str# "70만원"travelStyles: List[TravelStyle] # 여행 스타일 리스트highlights: List[TripHighlight] # 하이라이트 리스트fullPlan: str (alias='full_plan') # 전체 텍스트 계획dailySchedules: List[DailySchedule] # 일별 일정outboundTransportation: TripTransportation# 출발 교통편returnTransportation: TripTransportation# 귀환 교통편accommodations: List[TripAccommodation] # 숙소 리스트

📡 API 명세

Base URL

Production: http://52.78.55.147:8000
Local Development: http://localhost:8000

1. 여행 계획 생성

여행 계획 생성 요청

POST /Travel-PlanContent-Type: application/json
{
"companions": "친구",
"departure": "서울",
"destination": "제주도",
"start_date": "2025-12-13",
"end_date": "2025-12-15",
"style": ["자연과 함께", "여유롭게 힐링"],
"budget": "50만원~70만원"
}

응답 예시:

{
"travel_id": "37488429-3759-4320-9603-a0db0277bd56",
"title": "제주도 2박 3일 우정 여행",
"destination": "제주도",
"departure": "서울",
"start_date": "2025-12-13",
"end_date": "2025-12-15",
"companions": "친구",
"budget": "70만원",
"travel_styles": [
{"category": "자연과 함께"}
],
"highlights": [
{"content": "겨울 바다 만끽하며 우정 스냅 촬영"},
{"content": "따뜻한 온천으로 피로 풀기"},
{"content": "제주 흑돼지 맛집 탐방"}
],
"daily_schedules": [
{
"day": 1,
"date": "2025-12-13",
"schedules": [
{
"order_index": 1,
"time": "07:30",
"title": "비행기 탑승",
"description": "김포공항에서 진에어 LJ313편으로 제주로 출발"
}
]
}
],
"outbound_transportation": {
"origin": "김포공항",
"destination": "제주공항",
"name": "진에어LJ313",
"price": 45000
},
"return_transportation": {...},
"accommodations": [...]
}

2. 여행 목록 조회

전체 여행 목록

GET /travel-summaries

특정 여행 상세 조회

GET /travel-summary/{travel_id}

3. Spring Boot 연동

여행 계획 저장 (Spring Boot로 전송)

POST /save-plan/{travel_id}Response:
{
"success": true,
"message": "여행 계획이 Spring Boot 서버에 성공적으로 저장되었습니다.",
"spring_response": {
"id": 123,
"title": "제주도 2박 3일 우정 여행",
...
},
"fastapi_travel_id": "37488429-3759-4320-9603-a0db0277bd56"
}

🚀 설치 및 실행

배포 환경

현재 AWS EC2 (52.78.55.147)에 Docker Compose로 배포 운영 중입니다.

서버 정보

Docker Compose로 실행

# 서버에서 실행cd /path/to/TripTalk
docker-compose up -d
# 로그 확인
docker-compose logs -f fastapi
# 재시작
docker-compose restart fastapi
# 중지
docker-compose down

환경변수 설정

.env 파일:

# Google Gemini API Key
GOOGLE_API_KEY=your-google-gemini-api-key-here
# Spring Boot Server URL (배포 환경)
SPRING_BOOT_URL=http://52.78.55.147:8080

로컬 개발 환경 (선택사항)

요구사항

  • Python 3.11 이상
  • Google Gemini API Key

1. 가상환경 생성 및 활성화

# 가상환경 생성
python3 -m venv venv
# 활성화 (macOS/Linux)source venv/bin/activate

2. 패키지 설치

pip install -r requirements.txt

requirements.txt:

fastapi==0.115.5
uvicorn==0.34.0
pydantic==2.10.3
google-generativeai==0.8.3
httpx==0.28.1
python-dotenv==1.0.1

3. 환경변수 설정 (로컬)

.env 파일:

GOOGLE_API_KEY=your-api-key
SPRING_BOOT_URL=http://localhost:8080

4. 로컬 실행

# 개발 모드
uvicorn AI_Chat:app --reload --host 0.0.0.0 --port 8000

5. API 테스트

# 배포 서버 테스트
curl http://52.78.55.147:8000/travel-summaries
# 로컬 테스트
curl http://localhost:8000/travel-summaries

🐳 배포 환경 (Docker)

현재 배포 상태

Docker Compose로 운영 중이며, docker-compose.yml 설정:

version: "3.9"services:
fastapi:
build: .container_name: fastapi-serverports:
- "8000:8000"restart: alwaysenvironment:
GOOGLE_API_KEY: ${GOOGLE_API_KEY}SPRING_BOOT_URL: http://52.78.55.147:8080volumes:
- ./data:/app/data
- ./outputs:/app/outputs

Dockerfile

FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["uvicorn", "AI_Chat:app", "--host", "0.0.0.0", "--port", "8000"]

배포 관리 명령어

# 서버 배포 (처음 또는 코드 변경 시)
docker-compose up -d --build
# 서버 재시작
docker-compose restart
# 로그 확인
docker-compose logs -f fastapi
# 서버 중지
docker-compose down
# 컨테이너 상태 확인
docker-compose ps

🔗 Spring Boot 연동

연동 플로우

1. FastAPI에서 여행 계획 생성 → travel_data.json 저장
2. 사용자 확인 후 "저장" 버튼 클릭
3. FastAPI → Spring Boot API 호출
POST http://52.78.55.147:8080/api/trip-plan/from-fastapi
4. Spring Boot → MySQL DB 저장
5. 저장 결과 반환

데이터 변환 과정

FastAPI (snake_case) → Spring Boot (camelCase)

# TripPlan 모델 (FastAPI)plan_data=plan_response.model_dump(by_alias=True)
# startDate, endDate, dailySchedules... (camelCase)# Spring Boot로 전송 (배포 환경)asyncwithhttpx.AsyncClient() asclient:
response=awaitclient.post(
"http://52.78.55.147:8080/api/trip-plan/from-fastapi",
json=plan_data
)

Spring Boot CreateFromFastAPIDTO:

publicstaticclassCreateFromFastAPIDTO {
privateStringstartDate; // FastAPI에서 "startDate" 전송privateStringendDate;
privateStringbudget;
privateList<DailyScheduleDTO> dailySchedules;
// ...
}

배포 환경 구성

┌─────────────────┐
│ Client App │
│ (Mobile/Web) │
└────────┬────────┘
│
├──────────────────────┬─────────────────────┐
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ FastAPI Server │ │ Spring Boot API │ │ Google │
│ (Docker) │─>│ (AWS EC2) │ │ Gemini API │
│ Port: 8000 │ │ 52.78.55.147 │ └─────────────────┘
└─────────────────┘ └────────┬─────────┘
│ │
▼ ▼
┌─────────────────┐ ┌──────────────────┐
│ travel_data.json│ │ MySQL (RDS) │
│ (로컬 저장) │ │ (영구 저장) │
└─────────────────┘ └──────────────────┘

📂 프로젝트 구조

TripTalk/
├── AI_Chat.py # 메인 FastAPI 애플리케이션
├── main.py # 애플리케이션 엔트리 포인트
├── requirements.txt # Python 패키지 의존성
├── .env # 환경변수 (OpenAI API Key)
├── Dockerfile # Docker 이미지 빌드 파일
├── docker-compose.yml # Docker Compose 설정
├── README.md # 프로젝트 문서
├── data/
│ └── travel_data.json # 여행 계획 JSON 저장소
└── outputs/
└── latest_plan.md # 최신 여행 계획 마크다운

🔧 주요 기술적 특징

1. Pydantic Field Aliases

  • JSON 파일: start_date, end_date (snake_case)
  • Python 모델: startDate, endDate (camelCase)
  • Spring Boot 전송: startDate, endDate (camelCase)
classTripPlan(BaseModel):
startDate: str=Field(..., alias='start_date')
endDate: str=Field(..., alias='end_date')

2. Google Gemini Structured Output

  • Gemini 2.0 Flash의 자연어 기반 JSON 생성
  • Pydantic 모델과 일치하는 구조화된 응답
  • 파싱 에러 최소화

3. 중복 방지 로직

  • 동일 조건 (목적지, 기간, 동행자, 예산, 스타일) 시 기존 데이터 업데이트
  • 다른 조건 시 새 UUID 생성

4. 에러 핸들링

  • Spring Boot 통신 실패 시 재시도
  • Google Gemini API 타임아웃 처리
  • JSON 파싱 에러 복구

📝 커밋 메시지 규칙

타입(Type)설명(Description)
Feat새로운 기능을 추가한 경우
Fix에러·버그를 수정한 경우
DesignCSS 등 UI 디자인을 변경한 경우
HOTFIX급하게 치명적인 에러를 즉시 수정한 경우
Style코드 포맷 변경, 세미콜론 누락 등 로직 변경 없는 스타일 수정
Refactor기능 변화 없이 코드를 리팩토링한 경우
Comment주석 추가 또는 변경
Docs문서를 수정한 경우 (README 등)
Test테스트 코드 추가·변경·리팩토링
Chore기타 변경사항 (빌드, 패키지, 설정 파일 수정 등)
Rename파일·폴더명을 수정하거나 옮기는 경우

예시

git commit -m "Feat: Google Gemini 2.0 Flash 여행 계획 생성 API 추가"
git commit -m "Fix: Spring Boot 연동 시 camelCase 변환 오류 수정"
git commit -m "Docs: README 데이터 모델 섹션 추가"

🔄 버전 히스토리

v1.0.0 (2025-12-12)

  • ✅ Google Gemini 2.0 Flash 기반 여행 계획 생성
  • ✅ Pydantic 모델 기반 데이터 검증
  • ✅ JSON 파일 기반 영구 저장
  • ✅ Spring Boot API 연동 완료
  • ✅ camelCase/snake_case 자동 변환

🤖 TripTalk AI Server - 당신만의 완벽한 여행을 AI가 설계합니다!

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

🤖 TripTalk AI Server - FastAPI

Google Gemini 2.0 Flash 기반 맞춤형 여행 일정 생성 AI 서버

image

👥 팀 정보

📋 목차


🎯 프로젝트 개요

image

TripTalk AI Server는 사용자의 여행 스타일, 목적지, 예산, 동행인 정보를 기반으로 Google Gemini 2.0 Flash API를 활용하여 맞춤형 여행 일정을 자동 생성하는 FastAPI 기반 AI 서버입니다.

생성된 여행 계획은 JSON 파일로 임시 저장되며, 사용자 확인 후 Spring Boot 서버로 전송되어 MySQL DB에 영구 저장됩니다.

핵심 가치

  • 🤖 AI 맞춤 추천: Google Gemini 2.0 Flash 기반 개인화된 여행 일정 생성
  • 📅 상세 일정: 일별/시간대별 구체적인 여행 계획 (식당, 관광지, 교통편 포함)
  • 🏨 교통편/숙소 정보: 출발편, 귀환편, 숙소 예약 정보 자동 생성
  • 🔗 Spring Boot 연동: RESTful API 통신으로 완벽한 시스템 통합

✨ 주요 기능

1. 🗺️ AI 여행 일정 생성

  • Google Gemini 2.0 Flash API 연동

    • 사용자 입력 기반 프롬프트 생성
    • 자연어 기반 구조화된 JSON 응답
    • 9가지 여행 스타일 분석 (체험·액티비티, 자연과 함께, 여유롭게 힐링 등)
  • 상세 일정 생성

    • 일별 스케줄 (DailySchedule)
    • 시간대별 상세 계획 (ScheduleItem)
    • 실제 식당·관광지 이름 포함
    • 교통편 정보 (항공사명, 출발/도착 시간, 가격)
    • 숙소 정보 (호텔명, 주소, 1박 가격)
  • 하이라이트 추출

    • 여행의 주요 포인트 3-5개 자동 생성
    • 각 하이라이트 100자 이내
image

2. 📋 여행 계획 관리

  • JSON 파일 기반 저장

    • data/travel_data.json에 영구 저장
    • UUID 기반 고유 ID 생성
    • 중복 방지 로직 (동일 조건 시 업데이트)
  • 여행 목록 조회

    • 전체 여행 목록 반환
    • 특정 여행 상세 조회
image

3. 🔗 Spring Boot 연동

  • HTTP POST 통신

    • FastAPI → Spring Boot REST API 호출
    • JSON 데이터 자동 직렬화 (camelCase 변환)
    • 에러 핸들링 및 재시도 로직
  • 데이터 변환

    • Pydantic 모델 → JSON (by_alias=True)
    • snake_case → camelCase 자동 변환
    • Spring Boot DTO 형식에 맞춘 데이터 구조

🛠 기술 스택

Backend

  • Language: Python 3.11+
  • Framework: FastAPI 0.115.5
  • AI: Google Gemini 2.0 Flash API
  • Data Validation: Pydantic 2.10.3
  • HTTP Client: httpx 0.28.1
  • CORS: FastAPI CORS Middleware

Storage

  • File System: JSON 파일 기반 데이터 저장
  • Data Format: UTF-8 JSON (ensure_ascii=False)

External APIs

  • Google Gemini API: Gemini 2.0 Flash 기반 여행 일정 생성
  • Spring Boot API: 여행 계획 DB 저장

🏗 시스템 아키텍처

┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ Client │ ───> │ FastAPI │ ───> │ Google │
│ (Mobile) │ │ (AI Server) │ │ Gemini 2.0 │
└─────────────┘ └──────────────┘ └─────────────┘
│
├──────> Spring Boot API
│ (DB 저장)
│
└──────> data/travel_data.json
(임시 저장)

데이터 플로우

1. 사용자 입력 (목적지, 기간, 예산, 동행인, 여행 스타일)
↓
2. FastAPI → Google Gemini 2.0 Flash API 요청
↓
3. Gemini → 구조화된 여행 계획 JSON 생성
↓
4. FastAPI → Pydantic 모델 검증 및 저장 (travel_data.json)
↓
5. 사용자 확인 후 "저장" 버튼 클릭
↓
6. FastAPI → Spring Boot API 호출 (POST /api/trip-plan/from-fastapi)
↓
7. Spring Boot → MySQL DB 저장

📦 데이터 모델

Pydantic 모델 구조

TravelStyle (여행 스타일)

classTravelStyle(BaseModel):
category: str# "체험·액티비티", "자연과 함께", "여유롭게 힐링" 등

ScheduleItem (상세 일정)

classScheduleItem(BaseModel):
order_index: int# 순서time: str# "09:00"title: str# "김포공항 출발"description: str# "진에어 LJ313편으로 제주 출발"

DailySchedule (일별 일정)

classDailySchedule(BaseModel):
day: int# 1, 2, 3...date: str# "2025-12-13"schedules: List[ScheduleItem] # 상세 일정 리스트

TripTransportation (교통편)

classTripTransportation(BaseModel):
origin: str# "김포공항"destination: str# "제주공항"name: str# "진에어LJ313"price: int# 45000

TripAccommodation (숙소)

classTripAccommodation(BaseModel):
name: str# "제주신화월드 호텔"address: str# "제주 서귀포시..."pricePerNight: int# 200000

TripPlan (전체 여행 계획)

classTripPlan(BaseModel):
title: str# "제주도 2박 3일 우정 여행"destination: str# "제주도"departure: str# "서울"startDate: str (alias='start_date') # "2025-12-13"endDate: str (alias='end_date') # "2025-12-15"companions: str# "친구"budget: str# "70만원"travelStyles: List[TravelStyle] # 여행 스타일 리스트highlights: List[TripHighlight] # 하이라이트 리스트fullPlan: str (alias='full_plan') # 전체 텍스트 계획dailySchedules: List[DailySchedule] # 일별 일정outboundTransportation: TripTransportation# 출발 교통편returnTransportation: TripTransportation# 귀환 교통편accommodations: List[TripAccommodation] # 숙소 리스트

📡 API 명세

Base URL

Production: http://52.78.55.147:8000
Local Development: http://localhost:8000

1. 여행 계획 생성

여행 계획 생성 요청

POST /Travel-PlanContent-Type: application/json
{
"companions": "친구",
"departure": "서울",
"destination": "제주도",
"start_date": "2025-12-13",
"end_date": "2025-12-15",
"style": ["자연과 함께", "여유롭게 힐링"],
"budget": "50만원~70만원"
}

응답 예시:

{
"travel_id": "37488429-3759-4320-9603-a0db0277bd56",
"title": "제주도 2박 3일 우정 여행",
"destination": "제주도",
"departure": "서울",
"start_date": "2025-12-13",
"end_date": "2025-12-15",
"companions": "친구",
"budget": "70만원",
"travel_styles": [
{"category": "자연과 함께"}
],
"highlights": [
{"content": "겨울 바다 만끽하며 우정 스냅 촬영"},
{"content": "따뜻한 온천으로 피로 풀기"},
{"content": "제주 흑돼지 맛집 탐방"}
],
"daily_schedules": [
{
"day": 1,
"date": "2025-12-13",
"schedules": [
{
"order_index": 1,
"time": "07:30",
"title": "비행기 탑승",
"description": "김포공항에서 진에어 LJ313편으로 제주로 출발"
}
]
}
],
"outbound_transportation": {
"origin": "김포공항",
"destination": "제주공항",
"name": "진에어LJ313",
"price": 45000
},
"return_transportation": {...},
"accommodations": [...]
}

2. 여행 목록 조회

전체 여행 목록

GET /travel-summaries

특정 여행 상세 조회

GET /travel-summary/{travel_id}

3. Spring Boot 연동

여행 계획 저장 (Spring Boot로 전송)

POST /save-plan/{travel_id}Response:
{
"success": true,
"message": "여행 계획이 Spring Boot 서버에 성공적으로 저장되었습니다.",
"spring_response": {
"id": 123,
"title": "제주도 2박 3일 우정 여행",
...
},
"fastapi_travel_id": "37488429-3759-4320-9603-a0db0277bd56"
}

🚀 설치 및 실행

배포 환경

현재 AWS EC2 (52.78.55.147)에 Docker Compose로 배포 운영 중입니다.

서버 정보

Docker Compose로 실행

# 서버에서 실행cd /path/to/TripTalk
docker-compose up -d
# 로그 확인
docker-compose logs -f fastapi
# 재시작
docker-compose restart fastapi
# 중지
docker-compose down

환경변수 설정

.env 파일:

# Google Gemini API Key
GOOGLE_API_KEY=your-google-gemini-api-key-here
# Spring Boot Server URL (배포 환경)
SPRING_BOOT_URL=http://52.78.55.147:8080

로컬 개발 환경 (선택사항)

요구사항

  • Python 3.11 이상
  • Google Gemini API Key

1. 가상환경 생성 및 활성화

# 가상환경 생성
python3 -m venv venv
# 활성화 (macOS/Linux)source venv/bin/activate

2. 패키지 설치

pip install -r requirements.txt

requirements.txt:

fastapi==0.115.5
uvicorn==0.34.0
pydantic==2.10.3
google-generativeai==0.8.3
httpx==0.28.1
python-dotenv==1.0.1

3. 환경변수 설정 (로컬)

.env 파일:

GOOGLE_API_KEY=your-api-key
SPRING_BOOT_URL=http://localhost:8080

4. 로컬 실행

# 개발 모드
uvicorn AI_Chat:app --reload --host 0.0.0.0 --port 8000

5. API 테스트

# 배포 서버 테스트
curl http://52.78.55.147:8000/travel-summaries
# 로컬 테스트
curl http://localhost:8000/travel-summaries

🐳 배포 환경 (Docker)

현재 배포 상태

Docker Compose로 운영 중이며, docker-compose.yml 설정:

version: "3.9"services:
fastapi:
build: .container_name: fastapi-serverports:
- "8000:8000"restart: alwaysenvironment:
GOOGLE_API_KEY: ${GOOGLE_API_KEY}SPRING_BOOT_URL: http://52.78.55.147:8080volumes:
- ./data:/app/data
- ./outputs:/app/outputs

Dockerfile

FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["uvicorn", "AI_Chat:app", "--host", "0.0.0.0", "--port", "8000"]

배포 관리 명령어

# 서버 배포 (처음 또는 코드 변경 시)
docker-compose up -d --build
# 서버 재시작
docker-compose restart
# 로그 확인
docker-compose logs -f fastapi
# 서버 중지
docker-compose down
# 컨테이너 상태 확인
docker-compose ps

🔗 Spring Boot 연동

연동 플로우

1. FastAPI에서 여행 계획 생성 → travel_data.json 저장
2. 사용자 확인 후 "저장" 버튼 클릭
3. FastAPI → Spring Boot API 호출
POST http://52.78.55.147:8080/api/trip-plan/from-fastapi
4. Spring Boot → MySQL DB 저장
5. 저장 결과 반환

데이터 변환 과정

FastAPI (snake_case) → Spring Boot (camelCase)

# TripPlan 모델 (FastAPI)plan_data=plan_response.model_dump(by_alias=True)
# startDate, endDate, dailySchedules... (camelCase)# Spring Boot로 전송 (배포 환경)asyncwithhttpx.AsyncClient() asclient:
response=awaitclient.post(
"http://52.78.55.147:8080/api/trip-plan/from-fastapi",
json=plan_data
)

Spring Boot CreateFromFastAPIDTO:

publicstaticclassCreateFromFastAPIDTO {
privateStringstartDate; // FastAPI에서 "startDate" 전송privateStringendDate;
privateStringbudget;
privateList<DailyScheduleDTO> dailySchedules;
// ...
}

배포 환경 구성

┌─────────────────┐
│ Client App │
│ (Mobile/Web) │
└────────┬────────┘
│
├──────────────────────┬─────────────────────┐
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ FastAPI Server │ │ Spring Boot API │ │ Google │
│ (Docker) │─>│ (AWS EC2) │ │ Gemini API │
│ Port: 8000 │ │ 52.78.55.147 │ └─────────────────┘
└─────────────────┘ └────────┬─────────┘
│ │
▼ ▼
┌─────────────────┐ ┌──────────────────┐
│ travel_data.json│ │ MySQL (RDS) │
│ (로컬 저장) │ │ (영구 저장) │
└─────────────────┘ └──────────────────┘

📂 프로젝트 구조

TripTalk/
├── AI_Chat.py # 메인 FastAPI 애플리케이션
├── main.py # 애플리케이션 엔트리 포인트
├── requirements.txt # Python 패키지 의존성
├── .env # 환경변수 (OpenAI API Key)
├── Dockerfile # Docker 이미지 빌드 파일
├── docker-compose.yml # Docker Compose 설정
├── README.md # 프로젝트 문서
├── data/
│ └── travel_data.json # 여행 계획 JSON 저장소
└── outputs/
└── latest_plan.md # 최신 여행 계획 마크다운

🔧 주요 기술적 특징

1. Pydantic Field Aliases

  • JSON 파일: start_date, end_date (snake_case)
  • Python 모델: startDate, endDate (camelCase)
  • Spring Boot 전송: startDate, endDate (camelCase)
classTripPlan(BaseModel):
startDate: str=Field(..., alias='start_date')
endDate: str=Field(..., alias='end_date')

2. Google Gemini Structured Output

  • Gemini 2.0 Flash의 자연어 기반 JSON 생성
  • Pydantic 모델과 일치하는 구조화된 응답
  • 파싱 에러 최소화

3. 중복 방지 로직

  • 동일 조건 (목적지, 기간, 동행자, 예산, 스타일) 시 기존 데이터 업데이트
  • 다른 조건 시 새 UUID 생성

4. 에러 핸들링

  • Spring Boot 통신 실패 시 재시도
  • Google Gemini API 타임아웃 처리
  • JSON 파싱 에러 복구

📝 커밋 메시지 규칙

타입(Type)설명(Description)
Feat새로운 기능을 추가한 경우
Fix에러·버그를 수정한 경우
DesignCSS 등 UI 디자인을 변경한 경우
HOTFIX급하게 치명적인 에러를 즉시 수정한 경우
Style코드 포맷 변경, 세미콜론 누락 등 로직 변경 없는 스타일 수정
Refactor기능 변화 없이 코드를 리팩토링한 경우
Comment주석 추가 또는 변경
Docs문서를 수정한 경우 (README 등)
Test테스트 코드 추가·변경·리팩토링
Chore기타 변경사항 (빌드, 패키지, 설정 파일 수정 등)
Rename파일·폴더명을 수정하거나 옮기는 경우

예시

git commit -m "Feat: Google Gemini 2.0 Flash 여행 계획 생성 API 추가"
git commit -m "Fix: Spring Boot 연동 시 camelCase 변환 오류 수정"
git commit -m "Docs: README 데이터 모델 섹션 추가"

🔄 버전 히스토리

v1.0.0 (2025-12-12)

  • ✅ Google Gemini 2.0 Flash 기반 여행 계획 생성
  • ✅ Pydantic 모델 기반 데이터 검증
  • ✅ JSON 파일 기반 영구 저장
  • ✅ Spring Boot API 연동 완료
  • ✅ camelCase/snake_case 자동 변환

🤖 TripTalk AI Server - 당신만의 완벽한 여행을 AI가 설계합니다!

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

🤖 TripTalk AI Server - FastAPI

Google Gemini 2.0 Flash 기반 맞춤형 여행 일정 생성 AI 서버

image

👥 팀 정보

📋 목차


🎯 프로젝트 개요

image

TripTalk AI Server는 사용자의 여행 스타일, 목적지, 예산, 동행인 정보를 기반으로 Google Gemini 2.0 Flash API를 활용하여 맞춤형 여행 일정을 자동 생성하는 FastAPI 기반 AI 서버입니다.

생성된 여행 계획은 JSON 파일로 임시 저장되며, 사용자 확인 후 Spring Boot 서버로 전송되어 MySQL DB에 영구 저장됩니다.

핵심 가치

  • 🤖 AI 맞춤 추천: Google Gemini 2.0 Flash 기반 개인화된 여행 일정 생성
  • 📅 상세 일정: 일별/시간대별 구체적인 여행 계획 (식당, 관광지, 교통편 포함)
  • 🏨 교통편/숙소 정보: 출발편, 귀환편, 숙소 예약 정보 자동 생성
  • 🔗 Spring Boot 연동: RESTful API 통신으로 완벽한 시스템 통합

✨ 주요 기능

1. 🗺️ AI 여행 일정 생성

  • Google Gemini 2.0 Flash API 연동

    • 사용자 입력 기반 프롬프트 생성
    • 자연어 기반 구조화된 JSON 응답
    • 9가지 여행 스타일 분석 (체험·액티비티, 자연과 함께, 여유롭게 힐링 등)
  • 상세 일정 생성

    • 일별 스케줄 (DailySchedule)
    • 시간대별 상세 계획 (ScheduleItem)
    • 실제 식당·관광지 이름 포함
    • 교통편 정보 (항공사명, 출발/도착 시간, 가격)
    • 숙소 정보 (호텔명, 주소, 1박 가격)
  • 하이라이트 추출

    • 여행의 주요 포인트 3-5개 자동 생성
    • 각 하이라이트 100자 이내
image

2. 📋 여행 계획 관리

  • JSON 파일 기반 저장

    • data/travel_data.json에 영구 저장
    • UUID 기반 고유 ID 생성
    • 중복 방지 로직 (동일 조건 시 업데이트)
  • 여행 목록 조회

    • 전체 여행 목록 반환
    • 특정 여행 상세 조회
image

3. 🔗 Spring Boot 연동

  • HTTP POST 통신

    • FastAPI → Spring Boot REST API 호출
    • JSON 데이터 자동 직렬화 (camelCase 변환)
    • 에러 핸들링 및 재시도 로직
  • 데이터 변환

    • Pydantic 모델 → JSON (by_alias=True)
    • snake_case → camelCase 자동 변환
    • Spring Boot DTO 형식에 맞춘 데이터 구조

🛠 기술 스택

Backend

  • Language: Python 3.11+
  • Framework: FastAPI 0.115.5
  • AI: Google Gemini 2.0 Flash API
  • Data Validation: Pydantic 2.10.3
  • HTTP Client: httpx 0.28.1
  • CORS: FastAPI CORS Middleware

Storage

  • File System: JSON 파일 기반 데이터 저장
  • Data Format: UTF-8 JSON (ensure_ascii=False)

External APIs

  • Google Gemini API: Gemini 2.0 Flash 기반 여행 일정 생성
  • Spring Boot API: 여행 계획 DB 저장

🏗 시스템 아키텍처

┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ Client │ ───> │ FastAPI │ ───> │ Google │
│ (Mobile) │ │ (AI Server) │ │ Gemini 2.0 │
└─────────────┘ └──────────────┘ └─────────────┘
│
├──────> Spring Boot API
│ (DB 저장)
│
└──────> data/travel_data.json
(임시 저장)

데이터 플로우

1. 사용자 입력 (목적지, 기간, 예산, 동행인, 여행 스타일)
↓
2. FastAPI → Google Gemini 2.0 Flash API 요청
↓
3. Gemini → 구조화된 여행 계획 JSON 생성
↓
4. FastAPI → Pydantic 모델 검증 및 저장 (travel_data.json)
↓
5. 사용자 확인 후 "저장" 버튼 클릭
↓
6. FastAPI → Spring Boot API 호출 (POST /api/trip-plan/from-fastapi)
↓
7. Spring Boot → MySQL DB 저장

📦 데이터 모델

Pydantic 모델 구조

TravelStyle (여행 스타일)

classTravelStyle(BaseModel):
category: str# "체험·액티비티", "자연과 함께", "여유롭게 힐링" 등

ScheduleItem (상세 일정)

classScheduleItem(BaseModel):
order_index: int# 순서time: str# "09:00"title: str# "김포공항 출발"description: str# "진에어 LJ313편으로 제주 출발"

DailySchedule (일별 일정)

classDailySchedule(BaseModel):
day: int# 1, 2, 3...date: str# "2025-12-13"schedules: List[ScheduleItem] # 상세 일정 리스트

TripTransportation (교통편)

classTripTransportation(BaseModel):
origin: str# "김포공항"destination: str# "제주공항"name: str# "진에어LJ313"price: int# 45000

TripAccommodation (숙소)

classTripAccommodation(BaseModel):
name: str# "제주신화월드 호텔"address: str# "제주 서귀포시..."pricePerNight: int# 200000

TripPlan (전체 여행 계획)

classTripPlan(BaseModel):
title: str# "제주도 2박 3일 우정 여행"destination: str# "제주도"departure: str# "서울"startDate: str (alias='start_date') # "2025-12-13"endDate: str (alias='end_date') # "2025-12-15"companions: str# "친구"budget: str# "70만원"travelStyles: List[TravelStyle] # 여행 스타일 리스트highlights: List[TripHighlight] # 하이라이트 리스트fullPlan: str (alias='full_plan') # 전체 텍스트 계획dailySchedules: List[DailySchedule] # 일별 일정outboundTransportation: TripTransportation# 출발 교통편returnTransportation: TripTransportation# 귀환 교통편accommodations: List[TripAccommodation] # 숙소 리스트

📡 API 명세

Base URL

Production: http://52.78.55.147:8000
Local Development: http://localhost:8000

1. 여행 계획 생성

여행 계획 생성 요청

POST /Travel-PlanContent-Type: application/json
{
"companions": "친구",
"departure": "서울",
"destination": "제주도",
"start_date": "2025-12-13",
"end_date": "2025-12-15",
"style": ["자연과 함께", "여유롭게 힐링"],
"budget": "50만원~70만원"
}

응답 예시:

{
"travel_id": "37488429-3759-4320-9603-a0db0277bd56",
"title": "제주도 2박 3일 우정 여행",
"destination": "제주도",
"departure": "서울",
"start_date": "2025-12-13",
"end_date": "2025-12-15",
"companions": "친구",
"budget": "70만원",
"travel_styles": [
{"category": "자연과 함께"}
],
"highlights": [
{"content": "겨울 바다 만끽하며 우정 스냅 촬영"},
{"content": "따뜻한 온천으로 피로 풀기"},
{"content": "제주 흑돼지 맛집 탐방"}
],
"daily_schedules": [
{
"day": 1,
"date": "2025-12-13",
"schedules": [
{
"order_index": 1,
"time": "07:30",
"title": "비행기 탑승",
"description": "김포공항에서 진에어 LJ313편으로 제주로 출발"
}
]
}
],
"outbound_transportation": {
"origin": "김포공항",
"destination": "제주공항",
"name": "진에어LJ313",
"price": 45000
},
"return_transportation": {...},
"accommodations": [...]
}

2. 여행 목록 조회

전체 여행 목록

GET /travel-summaries

특정 여행 상세 조회

GET /travel-summary/{travel_id}

3. Spring Boot 연동

여행 계획 저장 (Spring Boot로 전송)

POST /save-plan/{travel_id}Response:
{
"success": true,
"message": "여행 계획이 Spring Boot 서버에 성공적으로 저장되었습니다.",
"spring_response": {
"id": 123,
"title": "제주도 2박 3일 우정 여행",
...
},
"fastapi_travel_id": "37488429-3759-4320-9603-a0db0277bd56"
}

🚀 설치 및 실행

배포 환경

현재 AWS EC2 (52.78.55.147)에 Docker Compose로 배포 운영 중입니다.

서버 정보

Docker Compose로 실행

# 서버에서 실행cd /path/to/TripTalk
docker-compose up -d
# 로그 확인
docker-compose logs -f fastapi
# 재시작
docker-compose restart fastapi
# 중지
docker-compose down

환경변수 설정

.env 파일:

# Google Gemini API Key
GOOGLE_API_KEY=your-google-gemini-api-key-here
# Spring Boot Server URL (배포 환경)
SPRING_BOOT_URL=http://52.78.55.147:8080

로컬 개발 환경 (선택사항)

요구사항

  • Python 3.11 이상
  • Google Gemini API Key

1. 가상환경 생성 및 활성화

# 가상환경 생성
python3 -m venv venv
# 활성화 (macOS/Linux)source venv/bin/activate

2. 패키지 설치

pip install -r requirements.txt

requirements.txt:

fastapi==0.115.5
uvicorn==0.34.0
pydantic==2.10.3
google-generativeai==0.8.3
httpx==0.28.1
python-dotenv==1.0.1

3. 환경변수 설정 (로컬)

.env 파일:

GOOGLE_API_KEY=your-api-key
SPRING_BOOT_URL=http://localhost:8080

4. 로컬 실행

# 개발 모드
uvicorn AI_Chat:app --reload --host 0.0.0.0 --port 8000

5. API 테스트

# 배포 서버 테스트
curl http://52.78.55.147:8000/travel-summaries
# 로컬 테스트
curl http://localhost:8000/travel-summaries

🐳 배포 환경 (Docker)

현재 배포 상태

Docker Compose로 운영 중이며, docker-compose.yml 설정:

version: "3.9"services:
fastapi:
build: .container_name: fastapi-serverports:
- "8000:8000"restart: alwaysenvironment:
GOOGLE_API_KEY: ${GOOGLE_API_KEY}SPRING_BOOT_URL: http://52.78.55.147:8080volumes:
- ./data:/app/data
- ./outputs:/app/outputs

Dockerfile

FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["uvicorn", "AI_Chat:app", "--host", "0.0.0.0", "--port", "8000"]

배포 관리 명령어

# 서버 배포 (처음 또는 코드 변경 시)
docker-compose up -d --build
# 서버 재시작
docker-compose restart
# 로그 확인
docker-compose logs -f fastapi
# 서버 중지
docker-compose down
# 컨테이너 상태 확인
docker-compose ps

🔗 Spring Boot 연동

연동 플로우

1. FastAPI에서 여행 계획 생성 → travel_data.json 저장
2. 사용자 확인 후 "저장" 버튼 클릭
3. FastAPI → Spring Boot API 호출
POST http://52.78.55.147:8080/api/trip-plan/from-fastapi
4. Spring Boot → MySQL DB 저장
5. 저장 결과 반환

데이터 변환 과정

FastAPI (snake_case) → Spring Boot (camelCase)

# TripPlan 모델 (FastAPI)plan_data=plan_response.model_dump(by_alias=True)
# startDate, endDate, dailySchedules... (camelCase)# Spring Boot로 전송 (배포 환경)asyncwithhttpx.AsyncClient() asclient:
response=awaitclient.post(
"http://52.78.55.147:8080/api/trip-plan/from-fastapi",
json=plan_data
)

Spring Boot CreateFromFastAPIDTO:

publicstaticclassCreateFromFastAPIDTO {
privateStringstartDate; // FastAPI에서 "startDate" 전송privateStringendDate;
privateStringbudget;
privateList<DailyScheduleDTO> dailySchedules;
// ...
}

배포 환경 구성

┌─────────────────┐
│ Client App │
│ (Mobile/Web) │
└────────┬────────┘
│
├──────────────────────┬─────────────────────┐
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ FastAPI Server │ │ Spring Boot API │ │ Google │
│ (Docker) │─>│ (AWS EC2) │ │ Gemini API │
│ Port: 8000 │ │ 52.78.55.147 │ └─────────────────┘
└─────────────────┘ └────────┬─────────┘
│ │
▼ ▼
┌─────────────────┐ ┌──────────────────┐
│ travel_data.json│ │ MySQL (RDS) │
│ (로컬 저장) │ │ (영구 저장) │
└─────────────────┘ └──────────────────┘

📂 프로젝트 구조

TripTalk/
├── AI_Chat.py # 메인 FastAPI 애플리케이션
├── main.py # 애플리케이션 엔트리 포인트
├── requirements.txt # Python 패키지 의존성
├── .env # 환경변수 (OpenAI API Key)
├── Dockerfile # Docker 이미지 빌드 파일
├── docker-compose.yml # Docker Compose 설정
├── README.md # 프로젝트 문서
├── data/
│ └── travel_data.json # 여행 계획 JSON 저장소
└── outputs/
└── latest_plan.md # 최신 여행 계획 마크다운

🔧 주요 기술적 특징

1. Pydantic Field Aliases

  • JSON 파일: start_date, end_date (snake_case)
  • Python 모델: startDate, endDate (camelCase)
  • Spring Boot 전송: startDate, endDate (camelCase)
classTripPlan(BaseModel):
startDate: str=Field(..., alias='start_date')
endDate: str=Field(..., alias='end_date')

2. Google Gemini Structured Output

  • Gemini 2.0 Flash의 자연어 기반 JSON 생성
  • Pydantic 모델과 일치하는 구조화된 응답
  • 파싱 에러 최소화

3. 중복 방지 로직

  • 동일 조건 (목적지, 기간, 동행자, 예산, 스타일) 시 기존 데이터 업데이트
  • 다른 조건 시 새 UUID 생성

4. 에러 핸들링

  • Spring Boot 통신 실패 시 재시도
  • Google Gemini API 타임아웃 처리
  • JSON 파싱 에러 복구

📝 커밋 메시지 규칙

타입(Type)설명(Description)
Feat새로운 기능을 추가한 경우
Fix에러·버그를 수정한 경우
DesignCSS 등 UI 디자인을 변경한 경우
HOTFIX급하게 치명적인 에러를 즉시 수정한 경우
Style코드 포맷 변경, 세미콜론 누락 등 로직 변경 없는 스타일 수정
Refactor기능 변화 없이 코드를 리팩토링한 경우
Comment주석 추가 또는 변경
Docs문서를 수정한 경우 (README 등)
Test테스트 코드 추가·변경·리팩토링
Chore기타 변경사항 (빌드, 패키지, 설정 파일 수정 등)
Rename파일·폴더명을 수정하거나 옮기는 경우

예시

git commit -m "Feat: Google Gemini 2.0 Flash 여행 계획 생성 API 추가"
git commit -m "Fix: Spring Boot 연동 시 camelCase 변환 오류 수정"
git commit -m "Docs: README 데이터 모델 섹션 추가"

🔄 버전 히스토리

v1.0.0 (2025-12-12)

  • ✅ Google Gemini 2.0 Flash 기반 여행 계획 생성
  • ✅ Pydantic 모델 기반 데이터 검증
  • ✅ JSON 파일 기반 영구 저장
  • ✅ Spring Boot API 연동 완료
  • ✅ camelCase/snake_case 자동 변환

🤖 TripTalk AI Server - 당신만의 완벽한 여행을 AI가 설계합니다!

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

🤖 TripTalk AI Server - FastAPI

Google Gemini 2.0 Flash 기반 맞춤형 여행 일정 생성 AI 서버

image

👥 팀 정보

📋 목차


🎯 프로젝트 개요

image

TripTalk AI Server는 사용자의 여행 스타일, 목적지, 예산, 동행인 정보를 기반으로 Google Gemini 2.0 Flash API를 활용하여 맞춤형 여행 일정을 자동 생성하는 FastAPI 기반 AI 서버입니다.

생성된 여행 계획은 JSON 파일로 임시 저장되며, 사용자 확인 후 Spring Boot 서버로 전송되어 MySQL DB에 영구 저장됩니다.

핵심 가치

  • 🤖 AI 맞춤 추천: Google Gemini 2.0 Flash 기반 개인화된 여행 일정 생성
  • 📅 상세 일정: 일별/시간대별 구체적인 여행 계획 (식당, 관광지, 교통편 포함)
  • 🏨 교통편/숙소 정보: 출발편, 귀환편, 숙소 예약 정보 자동 생성
  • 🔗 Spring Boot 연동: RESTful API 통신으로 완벽한 시스템 통합

✨ 주요 기능

1. 🗺️ AI 여행 일정 생성

  • Google Gemini 2.0 Flash API 연동

    • 사용자 입력 기반 프롬프트 생성
    • 자연어 기반 구조화된 JSON 응답
    • 9가지 여행 스타일 분석 (체험·액티비티, 자연과 함께, 여유롭게 힐링 등)
  • 상세 일정 생성

    • 일별 스케줄 (DailySchedule)
    • 시간대별 상세 계획 (ScheduleItem)
    • 실제 식당·관광지 이름 포함
    • 교통편 정보 (항공사명, 출발/도착 시간, 가격)
    • 숙소 정보 (호텔명, 주소, 1박 가격)
  • 하이라이트 추출

    • 여행의 주요 포인트 3-5개 자동 생성
    • 각 하이라이트 100자 이내
image

2. 📋 여행 계획 관리

  • JSON 파일 기반 저장

    • data/travel_data.json에 영구 저장
    • UUID 기반 고유 ID 생성
    • 중복 방지 로직 (동일 조건 시 업데이트)
  • 여행 목록 조회

    • 전체 여행 목록 반환
    • 특정 여행 상세 조회
image

3. 🔗 Spring Boot 연동

  • HTTP POST 통신

    • FastAPI → Spring Boot REST API 호출
    • JSON 데이터 자동 직렬화 (camelCase 변환)
    • 에러 핸들링 및 재시도 로직
  • 데이터 변환

    • Pydantic 모델 → JSON (by_alias=True)
    • snake_case → camelCase 자동 변환
    • Spring Boot DTO 형식에 맞춘 데이터 구조

🛠 기술 스택

Backend

  • Language: Python 3.11+
  • Framework: FastAPI 0.115.5
  • AI: Google Gemini 2.0 Flash API
  • Data Validation: Pydantic 2.10.3
  • HTTP Client: httpx 0.28.1
  • CORS: FastAPI CORS Middleware

Storage

  • File System: JSON 파일 기반 데이터 저장
  • Data Format: UTF-8 JSON (ensure_ascii=False)

External APIs

  • Google Gemini API: Gemini 2.0 Flash 기반 여행 일정 생성
  • Spring Boot API: 여행 계획 DB 저장

🏗 시스템 아키텍처

┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ Client │ ───> │ FastAPI │ ───> │ Google │
│ (Mobile) │ │ (AI Server) │ │ Gemini 2.0 │
└─────────────┘ └──────────────┘ └─────────────┘
│
├──────> Spring Boot API
│ (DB 저장)
│
└──────> data/travel_data.json
(임시 저장)

데이터 플로우

1. 사용자 입력 (목적지, 기간, 예산, 동행인, 여행 스타일)
↓
2. FastAPI → Google Gemini 2.0 Flash API 요청
↓
3. Gemini → 구조화된 여행 계획 JSON 생성
↓
4. FastAPI → Pydantic 모델 검증 및 저장 (travel_data.json)
↓
5. 사용자 확인 후 "저장" 버튼 클릭
↓
6. FastAPI → Spring Boot API 호출 (POST /api/trip-plan/from-fastapi)
↓
7. Spring Boot → MySQL DB 저장

📦 데이터 모델

Pydantic 모델 구조

TravelStyle (여행 스타일)

classTravelStyle(BaseModel):
category: str# "체험·액티비티", "자연과 함께", "여유롭게 힐링" 등

ScheduleItem (상세 일정)

classScheduleItem(BaseModel):
order_index: int# 순서time: str# "09:00"title: str# "김포공항 출발"description: str# "진에어 LJ313편으로 제주 출발"

DailySchedule (일별 일정)

classDailySchedule(BaseModel):
day: int# 1, 2, 3...date: str# "2025-12-13"schedules: List[ScheduleItem] # 상세 일정 리스트

TripTransportation (교통편)

classTripTransportation(BaseModel):
origin: str# "김포공항"destination: str# "제주공항"name: str# "진에어LJ313"price: int# 45000

TripAccommodation (숙소)

classTripAccommodation(BaseModel):
name: str# "제주신화월드 호텔"address: str# "제주 서귀포시..."pricePerNight: int# 200000

TripPlan (전체 여행 계획)

classTripPlan(BaseModel):
title: str# "제주도 2박 3일 우정 여행"destination: str# "제주도"departure: str# "서울"startDate: str (alias='start_date') # "2025-12-13"endDate: str (alias='end_date') # "2025-12-15"companions: str# "친구"budget: str# "70만원"travelStyles: List[TravelStyle] # 여행 스타일 리스트highlights: List[TripHighlight] # 하이라이트 리스트fullPlan: str (alias='full_plan') # 전체 텍스트 계획dailySchedules: List[DailySchedule] # 일별 일정outboundTransportation: TripTransportation# 출발 교통편returnTransportation: TripTransportation# 귀환 교통편accommodations: List[TripAccommodation] # 숙소 리스트

📡 API 명세

Base URL

Production: http://52.78.55.147:8000
Local Development: http://localhost:8000

1. 여행 계획 생성

여행 계획 생성 요청

POST /Travel-PlanContent-Type: application/json
{
"companions": "친구",
"departure": "서울",
"destination": "제주도",
"start_date": "2025-12-13",
"end_date": "2025-12-15",
"style": ["자연과 함께", "여유롭게 힐링"],
"budget": "50만원~70만원"
}

응답 예시:

{
"travel_id": "37488429-3759-4320-9603-a0db0277bd56",
"title": "제주도 2박 3일 우정 여행",
"destination": "제주도",
"departure": "서울",
"start_date": "2025-12-13",
"end_date": "2025-12-15",
"companions": "친구",
"budget": "70만원",
"travel_styles": [
{"category": "자연과 함께"}
],
"highlights": [
{"content": "겨울 바다 만끽하며 우정 스냅 촬영"},
{"content": "따뜻한 온천으로 피로 풀기"},
{"content": "제주 흑돼지 맛집 탐방"}
],
"daily_schedules": [
{
"day": 1,
"date": "2025-12-13",
"schedules": [
{
"order_index": 1,
"time": "07:30",
"title": "비행기 탑승",
"description": "김포공항에서 진에어 LJ313편으로 제주로 출발"
}
]
}
],
"outbound_transportation": {
"origin": "김포공항",
"destination": "제주공항",
"name": "진에어LJ313",
"price": 45000
},
"return_transportation": {...},
"accommodations": [...]
}

2. 여행 목록 조회

전체 여행 목록

GET /travel-summaries

특정 여행 상세 조회

GET /travel-summary/{travel_id}

3. Spring Boot 연동

여행 계획 저장 (Spring Boot로 전송)

POST /save-plan/{travel_id}Response:
{
"success": true,
"message": "여행 계획이 Spring Boot 서버에 성공적으로 저장되었습니다.",
"spring_response": {
"id": 123,
"title": "제주도 2박 3일 우정 여행",
...
},
"fastapi_travel_id": "37488429-3759-4320-9603-a0db0277bd56"
}

🚀 설치 및 실행

배포 환경

현재 AWS EC2 (52.78.55.147)에 Docker Compose로 배포 운영 중입니다.

서버 정보

Docker Compose로 실행

# 서버에서 실행cd /path/to/TripTalk
docker-compose up -d
# 로그 확인
docker-compose logs -f fastapi
# 재시작
docker-compose restart fastapi
# 중지
docker-compose down

환경변수 설정

.env 파일:

# Google Gemini API Key
GOOGLE_API_KEY=your-google-gemini-api-key-here
# Spring Boot Server URL (배포 환경)
SPRING_BOOT_URL=http://52.78.55.147:8080

로컬 개발 환경 (선택사항)

요구사항

  • Python 3.11 이상
  • Google Gemini API Key

1. 가상환경 생성 및 활성화

# 가상환경 생성
python3 -m venv venv
# 활성화 (macOS/Linux)source venv/bin/activate

2. 패키지 설치

pip install -r requirements.txt

requirements.txt:

fastapi==0.115.5
uvicorn==0.34.0
pydantic==2.10.3
google-generativeai==0.8.3
httpx==0.28.1
python-dotenv==1.0.1

3. 환경변수 설정 (로컬)

.env 파일:

GOOGLE_API_KEY=your-api-key
SPRING_BOOT_URL=http://localhost:8080

4. 로컬 실행

# 개발 모드
uvicorn AI_Chat:app --reload --host 0.0.0.0 --port 8000

5. API 테스트

# 배포 서버 테스트
curl http://52.78.55.147:8000/travel-summaries
# 로컬 테스트
curl http://localhost:8000/travel-summaries

🐳 배포 환경 (Docker)

현재 배포 상태

Docker Compose로 운영 중이며, docker-compose.yml 설정:

version: "3.9"services:
fastapi:
build: .container_name: fastapi-serverports:
- "8000:8000"restart: alwaysenvironment:
GOOGLE_API_KEY: ${GOOGLE_API_KEY}SPRING_BOOT_URL: http://52.78.55.147:8080volumes:
- ./data:/app/data
- ./outputs:/app/outputs

Dockerfile

FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["uvicorn", "AI_Chat:app", "--host", "0.0.0.0", "--port", "8000"]

배포 관리 명령어

# 서버 배포 (처음 또는 코드 변경 시)
docker-compose up -d --build
# 서버 재시작
docker-compose restart
# 로그 확인
docker-compose logs -f fastapi
# 서버 중지
docker-compose down
# 컨테이너 상태 확인
docker-compose ps

🔗 Spring Boot 연동

연동 플로우

1. FastAPI에서 여행 계획 생성 → travel_data.json 저장
2. 사용자 확인 후 "저장" 버튼 클릭
3. FastAPI → Spring Boot API 호출
POST http://52.78.55.147:8080/api/trip-plan/from-fastapi
4. Spring Boot → MySQL DB 저장
5. 저장 결과 반환

데이터 변환 과정

FastAPI (snake_case) → Spring Boot (camelCase)

# TripPlan 모델 (FastAPI)plan_data=plan_response.model_dump(by_alias=True)
# startDate, endDate, dailySchedules... (camelCase)# Spring Boot로 전송 (배포 환경)asyncwithhttpx.AsyncClient() asclient:
response=awaitclient.post(
"http://52.78.55.147:8080/api/trip-plan/from-fastapi",
json=plan_data
)

Spring Boot CreateFromFastAPIDTO:

publicstaticclassCreateFromFastAPIDTO {
privateStringstartDate; // FastAPI에서 "startDate" 전송privateStringendDate;
privateStringbudget;
privateList<DailyScheduleDTO> dailySchedules;
// ...
}

배포 환경 구성

┌─────────────────┐
│ Client App │
│ (Mobile/Web) │
└────────┬────────┘
│
├──────────────────────┬─────────────────────┐
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ FastAPI Server │ │ Spring Boot API │ │ Google │
│ (Docker) │─>│ (AWS EC2) │ │ Gemini API │
│ Port: 8000 │ │ 52.78.55.147 │ └─────────────────┘
└─────────────────┘ └────────┬─────────┘
│ │
▼ ▼
┌─────────────────┐ ┌──────────────────┐
│ travel_data.json│ │ MySQL (RDS) │
│ (로컬 저장) │ │ (영구 저장) │
└─────────────────┘ └──────────────────┘

📂 프로젝트 구조

TripTalk/
├── AI_Chat.py # 메인 FastAPI 애플리케이션
├── main.py # 애플리케이션 엔트리 포인트
├── requirements.txt # Python 패키지 의존성
├── .env # 환경변수 (OpenAI API Key)
├── Dockerfile # Docker 이미지 빌드 파일
├── docker-compose.yml # Docker Compose 설정
├── README.md # 프로젝트 문서
├── data/
│ └── travel_data.json # 여행 계획 JSON 저장소
└── outputs/
└── latest_plan.md # 최신 여행 계획 마크다운

🔧 주요 기술적 특징

1. Pydantic Field Aliases

  • JSON 파일: start_date, end_date (snake_case)
  • Python 모델: startDate, endDate (camelCase)
  • Spring Boot 전송: startDate, endDate (camelCase)
classTripPlan(BaseModel):
startDate: str=Field(..., alias='start_date')
endDate: str=Field(..., alias='end_date')

2. Google Gemini Structured Output

  • Gemini 2.0 Flash의 자연어 기반 JSON 생성
  • Pydantic 모델과 일치하는 구조화된 응답
  • 파싱 에러 최소화

3. 중복 방지 로직

  • 동일 조건 (목적지, 기간, 동행자, 예산, 스타일) 시 기존 데이터 업데이트
  • 다른 조건 시 새 UUID 생성

4. 에러 핸들링

  • Spring Boot 통신 실패 시 재시도
  • Google Gemini API 타임아웃 처리
  • JSON 파싱 에러 복구

📝 커밋 메시지 규칙

타입(Type)설명(Description)
Feat새로운 기능을 추가한 경우
Fix에러·버그를 수정한 경우
DesignCSS 등 UI 디자인을 변경한 경우
HOTFIX급하게 치명적인 에러를 즉시 수정한 경우
Style코드 포맷 변경, 세미콜론 누락 등 로직 변경 없는 스타일 수정
Refactor기능 변화 없이 코드를 리팩토링한 경우
Comment주석 추가 또는 변경
Docs문서를 수정한 경우 (README 등)
Test테스트 코드 추가·변경·리팩토링
Chore기타 변경사항 (빌드, 패키지, 설정 파일 수정 등)
Rename파일·폴더명을 수정하거나 옮기는 경우

예시

git commit -m "Feat: Google Gemini 2.0 Flash 여행 계획 생성 API 추가"
git commit -m "Fix: Spring Boot 연동 시 camelCase 변환 오류 수정"
git commit -m "Docs: README 데이터 모델 섹션 추가"

🔄 버전 히스토리

v1.0.0 (2025-12-12)

  • ✅ Google Gemini 2.0 Flash 기반 여행 계획 생성
  • ✅ Pydantic 모델 기반 데이터 검증
  • ✅ JSON 파일 기반 영구 저장
  • ✅ Spring Boot API 연동 완료
  • ✅ camelCase/snake_case 자동 변환

🤖 TripTalk AI Server - 당신만의 완벽한 여행을 AI가 설계합니다!

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

🤖 TripTalk AI Server - FastAPI

Google Gemini 2.0 Flash 기반 맞춤형 여행 일정 생성 AI 서버

image

👥 팀 정보

📋 목차


🎯 프로젝트 개요

image

TripTalk AI Server는 사용자의 여행 스타일, 목적지, 예산, 동행인 정보를 기반으로 Google Gemini 2.0 Flash API를 활용하여 맞춤형 여행 일정을 자동 생성하는 FastAPI 기반 AI 서버입니다.

생성된 여행 계획은 JSON 파일로 임시 저장되며, 사용자 확인 후 Spring Boot 서버로 전송되어 MySQL DB에 영구 저장됩니다.

핵심 가치

  • 🤖 AI 맞춤 추천: Google Gemini 2.0 Flash 기반 개인화된 여행 일정 생성
  • 📅 상세 일정: 일별/시간대별 구체적인 여행 계획 (식당, 관광지, 교통편 포함)
  • 🏨 교통편/숙소 정보: 출발편, 귀환편, 숙소 예약 정보 자동 생성
  • 🔗 Spring Boot 연동: RESTful API 통신으로 완벽한 시스템 통합

✨ 주요 기능

1. 🗺️ AI 여행 일정 생성

  • Google Gemini 2.0 Flash API 연동

    • 사용자 입력 기반 프롬프트 생성
    • 자연어 기반 구조화된 JSON 응답
    • 9가지 여행 스타일 분석 (체험·액티비티, 자연과 함께, 여유롭게 힐링 등)
  • 상세 일정 생성

    • 일별 스케줄 (DailySchedule)
    • 시간대별 상세 계획 (ScheduleItem)
    • 실제 식당·관광지 이름 포함
    • 교통편 정보 (항공사명, 출발/도착 시간, 가격)
    • 숙소 정보 (호텔명, 주소, 1박 가격)
  • 하이라이트 추출

    • 여행의 주요 포인트 3-5개 자동 생성
    • 각 하이라이트 100자 이내
image

2. 📋 여행 계획 관리

  • JSON 파일 기반 저장

    • data/travel_data.json에 영구 저장
    • UUID 기반 고유 ID 생성
    • 중복 방지 로직 (동일 조건 시 업데이트)
  • 여행 목록 조회

    • 전체 여행 목록 반환
    • 특정 여행 상세 조회
image

3. 🔗 Spring Boot 연동

  • HTTP POST 통신

    • FastAPI → Spring Boot REST API 호출
    • JSON 데이터 자동 직렬화 (camelCase 변환)
    • 에러 핸들링 및 재시도 로직
  • 데이터 변환

    • Pydantic 모델 → JSON (by_alias=True)
    • snake_case → camelCase 자동 변환
    • Spring Boot DTO 형식에 맞춘 데이터 구조

🛠 기술 스택

Backend

  • Language: Python 3.11+
  • Framework: FastAPI 0.115.5
  • AI: Google Gemini 2.0 Flash API
  • Data Validation: Pydantic 2.10.3
  • HTTP Client: httpx 0.28.1
  • CORS: FastAPI CORS Middleware

Storage

  • File System: JSON 파일 기반 데이터 저장
  • Data Format: UTF-8 JSON (ensure_ascii=False)

External APIs

  • Google Gemini API: Gemini 2.0 Flash 기반 여행 일정 생성
  • Spring Boot API: 여행 계획 DB 저장

🏗 시스템 아키텍처

┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ Client │ ───> │ FastAPI │ ───> │ Google │
│ (Mobile) │ │ (AI Server) │ │ Gemini 2.0 │
└─────────────┘ └──────────────┘ └─────────────┘
│
├──────> Spring Boot API
│ (DB 저장)
│
└──────> data/travel_data.json
(임시 저장)

데이터 플로우

1. 사용자 입력 (목적지, 기간, 예산, 동행인, 여행 스타일)
↓
2. FastAPI → Google Gemini 2.0 Flash API 요청
↓
3. Gemini → 구조화된 여행 계획 JSON 생성
↓
4. FastAPI → Pydantic 모델 검증 및 저장 (travel_data.json)
↓
5. 사용자 확인 후 "저장" 버튼 클릭
↓
6. FastAPI → Spring Boot API 호출 (POST /api/trip-plan/from-fastapi)
↓
7. Spring Boot → MySQL DB 저장

📦 데이터 모델

Pydantic 모델 구조

TravelStyle (여행 스타일)

classTravelStyle(BaseModel):
category: str# "체험·액티비티", "자연과 함께", "여유롭게 힐링" 등

ScheduleItem (상세 일정)

classScheduleItem(BaseModel):
order_index: int# 순서time: str# "09:00"title: str# "김포공항 출발"description: str# "진에어 LJ313편으로 제주 출발"

DailySchedule (일별 일정)

classDailySchedule(BaseModel):
day: int# 1, 2, 3...date: str# "2025-12-13"schedules: List[ScheduleItem] # 상세 일정 리스트

TripTransportation (교통편)

classTripTransportation(BaseModel):
origin: str# "김포공항"destination: str# "제주공항"name: str# "진에어LJ313"price: int# 45000

TripAccommodation (숙소)

classTripAccommodation(BaseModel):
name: str# "제주신화월드 호텔"address: str# "제주 서귀포시..."pricePerNight: int# 200000

TripPlan (전체 여행 계획)

classTripPlan(BaseModel):
title: str# "제주도 2박 3일 우정 여행"destination: str# "제주도"departure: str# "서울"startDate: str (alias='start_date') # "2025-12-13"endDate: str (alias='end_date') # "2025-12-15"companions: str# "친구"budget: str# "70만원"travelStyles: List[TravelStyle] # 여행 스타일 리스트highlights: List[TripHighlight] # 하이라이트 리스트fullPlan: str (alias='full_plan') # 전체 텍스트 계획dailySchedules: List[DailySchedule] # 일별 일정outboundTransportation: TripTransportation# 출발 교통편returnTransportation: TripTransportation# 귀환 교통편accommodations: List[TripAccommodation] # 숙소 리스트

📡 API 명세

Base URL

Production: http://52.78.55.147:8000
Local Development: http://localhost:8000

1. 여행 계획 생성

여행 계획 생성 요청

POST /Travel-PlanContent-Type: application/json
{
"companions": "친구",
"departure": "서울",
"destination": "제주도",
"start_date": "2025-12-13",
"end_date": "2025-12-15",
"style": ["자연과 함께", "여유롭게 힐링"],
"budget": "50만원~70만원"
}

응답 예시:

{
"travel_id": "37488429-3759-4320-9603-a0db0277bd56",
"title": "제주도 2박 3일 우정 여행",
"destination": "제주도",
"departure": "서울",
"start_date": "2025-12-13",
"end_date": "2025-12-15",
"companions": "친구",
"budget": "70만원",
"travel_styles": [
{"category": "자연과 함께"}
],
"highlights": [
{"content": "겨울 바다 만끽하며 우정 스냅 촬영"},
{"content": "따뜻한 온천으로 피로 풀기"},
{"content": "제주 흑돼지 맛집 탐방"}
],
"daily_schedules": [
{
"day": 1,
"date": "2025-12-13",
"schedules": [
{
"order_index": 1,
"time": "07:30",
"title": "비행기 탑승",
"description": "김포공항에서 진에어 LJ313편으로 제주로 출발"
}
]
}
],
"outbound_transportation": {
"origin": "김포공항",
"destination": "제주공항",
"name": "진에어LJ313",
"price": 45000
},
"return_transportation": {...},
"accommodations": [...]
}

2. 여행 목록 조회

전체 여행 목록

GET /travel-summaries

특정 여행 상세 조회

GET /travel-summary/{travel_id}

3. Spring Boot 연동

여행 계획 저장 (Spring Boot로 전송)

POST /save-plan/{travel_id}Response:
{
"success": true,
"message": "여행 계획이 Spring Boot 서버에 성공적으로 저장되었습니다.",
"spring_response": {
"id": 123,
"title": "제주도 2박 3일 우정 여행",
...
},
"fastapi_travel_id": "37488429-3759-4320-9603-a0db0277bd56"
}

🚀 설치 및 실행

배포 환경

현재 AWS EC2 (52.78.55.147)에 Docker Compose로 배포 운영 중입니다.

서버 정보

Docker Compose로 실행

# 서버에서 실행cd /path/to/TripTalk
docker-compose up -d
# 로그 확인
docker-compose logs -f fastapi
# 재시작
docker-compose restart fastapi
# 중지
docker-compose down

환경변수 설정

.env 파일:

# Google Gemini API Key
GOOGLE_API_KEY=your-google-gemini-api-key-here
# Spring Boot Server URL (배포 환경)
SPRING_BOOT_URL=http://52.78.55.147:8080

로컬 개발 환경 (선택사항)

요구사항

  • Python 3.11 이상
  • Google Gemini API Key

1. 가상환경 생성 및 활성화

# 가상환경 생성
python3 -m venv venv
# 활성화 (macOS/Linux)source venv/bin/activate

2. 패키지 설치

pip install -r requirements.txt

requirements.txt:

fastapi==0.115.5
uvicorn==0.34.0
pydantic==2.10.3
google-generativeai==0.8.3
httpx==0.28.1
python-dotenv==1.0.1

3. 환경변수 설정 (로컬)

.env 파일:

GOOGLE_API_KEY=your-api-key
SPRING_BOOT_URL=http://localhost:8080

4. 로컬 실행

# 개발 모드
uvicorn AI_Chat:app --reload --host 0.0.0.0 --port 8000

5. API 테스트

# 배포 서버 테스트
curl http://52.78.55.147:8000/travel-summaries
# 로컬 테스트
curl http://localhost:8000/travel-summaries

🐳 배포 환경 (Docker)

현재 배포 상태

Docker Compose로 운영 중이며, docker-compose.yml 설정:

version: "3.9"services:
fastapi:
build: .container_name: fastapi-serverports:
- "8000:8000"restart: alwaysenvironment:
GOOGLE_API_KEY: ${GOOGLE_API_KEY}SPRING_BOOT_URL: http://52.78.55.147:8080volumes:
- ./data:/app/data
- ./outputs:/app/outputs

Dockerfile

FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["uvicorn", "AI_Chat:app", "--host", "0.0.0.0", "--port", "8000"]

배포 관리 명령어

# 서버 배포 (처음 또는 코드 변경 시)
docker-compose up -d --build
# 서버 재시작
docker-compose restart
# 로그 확인
docker-compose logs -f fastapi
# 서버 중지
docker-compose down
# 컨테이너 상태 확인
docker-compose ps

🔗 Spring Boot 연동

연동 플로우

1. FastAPI에서 여행 계획 생성 → travel_data.json 저장
2. 사용자 확인 후 "저장" 버튼 클릭
3. FastAPI → Spring Boot API 호출
POST http://52.78.55.147:8080/api/trip-plan/from-fastapi
4. Spring Boot → MySQL DB 저장
5. 저장 결과 반환

데이터 변환 과정

FastAPI (snake_case) → Spring Boot (camelCase)

# TripPlan 모델 (FastAPI)plan_data=plan_response.model_dump(by_alias=True)
# startDate, endDate, dailySchedules... (camelCase)# Spring Boot로 전송 (배포 환경)asyncwithhttpx.AsyncClient() asclient:
response=awaitclient.post(
"http://52.78.55.147:8080/api/trip-plan/from-fastapi",
json=plan_data
)

Spring Boot CreateFromFastAPIDTO:

publicstaticclassCreateFromFastAPIDTO {
privateStringstartDate; // FastAPI에서 "startDate" 전송privateStringendDate;
privateStringbudget;
privateList<DailyScheduleDTO> dailySchedules;
// ...
}

배포 환경 구성

┌─────────────────┐
│ Client App │
│ (Mobile/Web) │
└────────┬────────┘
│
├──────────────────────┬─────────────────────┐
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ FastAPI Server │ │ Spring Boot API │ │ Google │
│ (Docker) │─>│ (AWS EC2) │ │ Gemini API │
│ Port: 8000 │ │ 52.78.55.147 │ └─────────────────┘
└─────────────────┘ └────────┬─────────┘
│ │
▼ ▼
┌─────────────────┐ ┌──────────────────┐
│ travel_data.json│ │ MySQL (RDS) │
│ (로컬 저장) │ │ (영구 저장) │
└─────────────────┘ └──────────────────┘

📂 프로젝트 구조

TripTalk/
├── AI_Chat.py # 메인 FastAPI 애플리케이션
├── main.py # 애플리케이션 엔트리 포인트
├── requirements.txt # Python 패키지 의존성
├── .env # 환경변수 (OpenAI API Key)
├── Dockerfile # Docker 이미지 빌드 파일
├── docker-compose.yml # Docker Compose 설정
├── README.md # 프로젝트 문서
├── data/
│ └── travel_data.json # 여행 계획 JSON 저장소
└── outputs/
└── latest_plan.md # 최신 여행 계획 마크다운

🔧 주요 기술적 특징

1. Pydantic Field Aliases

  • JSON 파일: start_date, end_date (snake_case)
  • Python 모델: startDate, endDate (camelCase)
  • Spring Boot 전송: startDate, endDate (camelCase)
classTripPlan(BaseModel):
startDate: str=Field(..., alias='start_date')
endDate: str=Field(..., alias='end_date')

2. Google Gemini Structured Output

  • Gemini 2.0 Flash의 자연어 기반 JSON 생성
  • Pydantic 모델과 일치하는 구조화된 응답
  • 파싱 에러 최소화

3. 중복 방지 로직

  • 동일 조건 (목적지, 기간, 동행자, 예산, 스타일) 시 기존 데이터 업데이트
  • 다른 조건 시 새 UUID 생성

4. 에러 핸들링

  • Spring Boot 통신 실패 시 재시도
  • Google Gemini API 타임아웃 처리
  • JSON 파싱 에러 복구

📝 커밋 메시지 규칙

타입(Type)설명(Description)
Feat새로운 기능을 추가한 경우
Fix에러·버그를 수정한 경우
DesignCSS 등 UI 디자인을 변경한 경우
HOTFIX급하게 치명적인 에러를 즉시 수정한 경우
Style코드 포맷 변경, 세미콜론 누락 등 로직 변경 없는 스타일 수정
Refactor기능 변화 없이 코드를 리팩토링한 경우
Comment주석 추가 또는 변경
Docs문서를 수정한 경우 (README 등)
Test테스트 코드 추가·변경·리팩토링
Chore기타 변경사항 (빌드, 패키지, 설정 파일 수정 등)
Rename파일·폴더명을 수정하거나 옮기는 경우

예시

git commit -m "Feat: Google Gemini 2.0 Flash 여행 계획 생성 API 추가"
git commit -m "Fix: Spring Boot 연동 시 camelCase 변환 오류 수정"
git commit -m "Docs: README 데이터 모델 섹션 추가"

🔄 버전 히스토리

v1.0.0 (2025-12-12)

  • ✅ Google Gemini 2.0 Flash 기반 여행 계획 생성
  • ✅ Pydantic 모델 기반 데이터 검증
  • ✅ JSON 파일 기반 영구 저장
  • ✅ Spring Boot API 연동 완료
  • ✅ camelCase/snake_case 자동 변환

🤖 TripTalk AI Server - 당신만의 완벽한 여행을 AI가 설계합니다!

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

🤖 TripTalk AI Server - FastAPI

Google Gemini 2.0 Flash 기반 맞춤형 여행 일정 생성 AI 서버

image

👥 팀 정보

📋 목차


🎯 프로젝트 개요

image

TripTalk AI Server는 사용자의 여행 스타일, 목적지, 예산, 동행인 정보를 기반으로 Google Gemini 2.0 Flash API를 활용하여 맞춤형 여행 일정을 자동 생성하는 FastAPI 기반 AI 서버입니다.

생성된 여행 계획은 JSON 파일로 임시 저장되며, 사용자 확인 후 Spring Boot 서버로 전송되어 MySQL DB에 영구 저장됩니다.

핵심 가치

  • 🤖 AI 맞춤 추천: Google Gemini 2.0 Flash 기반 개인화된 여행 일정 생성
  • 📅 상세 일정: 일별/시간대별 구체적인 여행 계획 (식당, 관광지, 교통편 포함)
  • 🏨 교통편/숙소 정보: 출발편, 귀환편, 숙소 예약 정보 자동 생성
  • 🔗 Spring Boot 연동: RESTful API 통신으로 완벽한 시스템 통합

✨ 주요 기능

1. 🗺️ AI 여행 일정 생성

  • Google Gemini 2.0 Flash API 연동

    • 사용자 입력 기반 프롬프트 생성
    • 자연어 기반 구조화된 JSON 응답
    • 9가지 여행 스타일 분석 (체험·액티비티, 자연과 함께, 여유롭게 힐링 등)
  • 상세 일정 생성

    • 일별 스케줄 (DailySchedule)
    • 시간대별 상세 계획 (ScheduleItem)
    • 실제 식당·관광지 이름 포함
    • 교통편 정보 (항공사명, 출발/도착 시간, 가격)
    • 숙소 정보 (호텔명, 주소, 1박 가격)
  • 하이라이트 추출

    • 여행의 주요 포인트 3-5개 자동 생성
    • 각 하이라이트 100자 이내
image

2. 📋 여행 계획 관리

  • JSON 파일 기반 저장

    • data/travel_data.json에 영구 저장
    • UUID 기반 고유 ID 생성
    • 중복 방지 로직 (동일 조건 시 업데이트)
  • 여행 목록 조회

    • 전체 여행 목록 반환
    • 특정 여행 상세 조회
image

3. 🔗 Spring Boot 연동

  • HTTP POST 통신

    • FastAPI → Spring Boot REST API 호출
    • JSON 데이터 자동 직렬화 (camelCase 변환)
    • 에러 핸들링 및 재시도 로직
  • 데이터 변환

    • Pydantic 모델 → JSON (by_alias=True)
    • snake_case → camelCase 자동 변환
    • Spring Boot DTO 형식에 맞춘 데이터 구조

🛠 기술 스택

Backend

  • Language: Python 3.11+
  • Framework: FastAPI 0.115.5
  • AI: Google Gemini 2.0 Flash API
  • Data Validation: Pydantic 2.10.3
  • HTTP Client: httpx 0.28.1
  • CORS: FastAPI CORS Middleware

Storage

  • File System: JSON 파일 기반 데이터 저장
  • Data Format: UTF-8 JSON (ensure_ascii=False)

External APIs

  • Google Gemini API: Gemini 2.0 Flash 기반 여행 일정 생성
  • Spring Boot API: 여행 계획 DB 저장

🏗 시스템 아키텍처

┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ Client │ ───> │ FastAPI │ ───> │ Google │
│ (Mobile) │ │ (AI Server) │ │ Gemini 2.0 │
└─────────────┘ └──────────────┘ └─────────────┘
│
├──────> Spring Boot API
│ (DB 저장)
│
└──────> data/travel_data.json
(임시 저장)

데이터 플로우

1. 사용자 입력 (목적지, 기간, 예산, 동행인, 여행 스타일)
↓
2. FastAPI → Google Gemini 2.0 Flash API 요청
↓
3. Gemini → 구조화된 여행 계획 JSON 생성
↓
4. FastAPI → Pydantic 모델 검증 및 저장 (travel_data.json)
↓
5. 사용자 확인 후 "저장" 버튼 클릭
↓
6. FastAPI → Spring Boot API 호출 (POST /api/trip-plan/from-fastapi)
↓
7. Spring Boot → MySQL DB 저장

📦 데이터 모델

Pydantic 모델 구조

TravelStyle (여행 스타일)

classTravelStyle(BaseModel):
category: str# "체험·액티비티", "자연과 함께", "여유롭게 힐링" 등

ScheduleItem (상세 일정)

classScheduleItem(BaseModel):
order_index: int# 순서time: str# "09:00"title: str# "김포공항 출발"description: str# "진에어 LJ313편으로 제주 출발"

DailySchedule (일별 일정)

classDailySchedule(BaseModel):
day: int# 1, 2, 3...date: str# "2025-12-13"schedules: List[ScheduleItem] # 상세 일정 리스트

TripTransportation (교통편)

classTripTransportation(BaseModel):
origin: str# "김포공항"destination: str# "제주공항"name: str# "진에어LJ313"price: int# 45000

TripAccommodation (숙소)

classTripAccommodation(BaseModel):
name: str# "제주신화월드 호텔"address: str# "제주 서귀포시..."pricePerNight: int# 200000

TripPlan (전체 여행 계획)

classTripPlan(BaseModel):
title: str# "제주도 2박 3일 우정 여행"destination: str# "제주도"departure: str# "서울"startDate: str (alias='start_date') # "2025-12-13"endDate: str (alias='end_date') # "2025-12-15"companions: str# "친구"budget: str# "70만원"travelStyles: List[TravelStyle] # 여행 스타일 리스트highlights: List[TripHighlight] # 하이라이트 리스트fullPlan: str (alias='full_plan') # 전체 텍스트 계획dailySchedules: List[DailySchedule] # 일별 일정outboundTransportation: TripTransportation# 출발 교통편returnTransportation: TripTransportation# 귀환 교통편accommodations: List[TripAccommodation] # 숙소 리스트

📡 API 명세

Base URL

Production: http://52.78.55.147:8000
Local Development: http://localhost:8000

1. 여행 계획 생성

여행 계획 생성 요청

POST /Travel-PlanContent-Type: application/json
{
"companions": "친구",
"departure": "서울",
"destination": "제주도",
"start_date": "2025-12-13",
"end_date": "2025-12-15",
"style": ["자연과 함께", "여유롭게 힐링"],
"budget": "50만원~70만원"
}

응답 예시:

{
"travel_id": "37488429-3759-4320-9603-a0db0277bd56",
"title": "제주도 2박 3일 우정 여행",
"destination": "제주도",
"departure": "서울",
"start_date": "2025-12-13",
"end_date": "2025-12-15",
"companions": "친구",
"budget": "70만원",
"travel_styles": [
{"category": "자연과 함께"}
],
"highlights": [
{"content": "겨울 바다 만끽하며 우정 스냅 촬영"},
{"content": "따뜻한 온천으로 피로 풀기"},
{"content": "제주 흑돼지 맛집 탐방"}
],
"daily_schedules": [
{
"day": 1,
"date": "2025-12-13",
"schedules": [
{
"order_index": 1,
"time": "07:30",
"title": "비행기 탑승",
"description": "김포공항에서 진에어 LJ313편으로 제주로 출발"
}
]
}
],
"outbound_transportation": {
"origin": "김포공항",
"destination": "제주공항",
"name": "진에어LJ313",
"price": 45000
},
"return_transportation": {...},
"accommodations": [...]
}

2. 여행 목록 조회

전체 여행 목록

GET /travel-summaries

특정 여행 상세 조회

GET /travel-summary/{travel_id}

3. Spring Boot 연동

여행 계획 저장 (Spring Boot로 전송)

POST /save-plan/{travel_id}Response:
{
"success": true,
"message": "여행 계획이 Spring Boot 서버에 성공적으로 저장되었습니다.",
"spring_response": {
"id": 123,
"title": "제주도 2박 3일 우정 여행",
...
},
"fastapi_travel_id": "37488429-3759-4320-9603-a0db0277bd56"
}

🚀 설치 및 실행

배포 환경

현재 AWS EC2 (52.78.55.147)에 Docker Compose로 배포 운영 중입니다.

서버 정보

Docker Compose로 실행

# 서버에서 실행cd /path/to/TripTalk
docker-compose up -d
# 로그 확인
docker-compose logs -f fastapi
# 재시작
docker-compose restart fastapi
# 중지
docker-compose down

환경변수 설정

.env 파일:

# Google Gemini API Key
GOOGLE_API_KEY=your-google-gemini-api-key-here
# Spring Boot Server URL (배포 환경)
SPRING_BOOT_URL=http://52.78.55.147:8080

로컬 개발 환경 (선택사항)

요구사항

  • Python 3.11 이상
  • Google Gemini API Key

1. 가상환경 생성 및 활성화

# 가상환경 생성
python3 -m venv venv
# 활성화 (macOS/Linux)source venv/bin/activate

2. 패키지 설치

pip install -r requirements.txt

requirements.txt:

fastapi==0.115.5
uvicorn==0.34.0
pydantic==2.10.3
google-generativeai==0.8.3
httpx==0.28.1
python-dotenv==1.0.1

3. 환경변수 설정 (로컬)

.env 파일:

GOOGLE_API_KEY=your-api-key
SPRING_BOOT_URL=http://localhost:8080

4. 로컬 실행

# 개발 모드
uvicorn AI_Chat:app --reload --host 0.0.0.0 --port 8000

5. API 테스트

# 배포 서버 테스트
curl http://52.78.55.147:8000/travel-summaries
# 로컬 테스트
curl http://localhost:8000/travel-summaries

🐳 배포 환경 (Docker)

현재 배포 상태

Docker Compose로 운영 중이며, docker-compose.yml 설정:

version: "3.9"services:
fastapi:
build: .container_name: fastapi-serverports:
- "8000:8000"restart: alwaysenvironment:
GOOGLE_API_KEY: ${GOOGLE_API_KEY}SPRING_BOOT_URL: http://52.78.55.147:8080volumes:
- ./data:/app/data
- ./outputs:/app/outputs

Dockerfile

FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["uvicorn", "AI_Chat:app", "--host", "0.0.0.0", "--port", "8000"]

배포 관리 명령어

# 서버 배포 (처음 또는 코드 변경 시)
docker-compose up -d --build
# 서버 재시작
docker-compose restart
# 로그 확인
docker-compose logs -f fastapi
# 서버 중지
docker-compose down
# 컨테이너 상태 확인
docker-compose ps

🔗 Spring Boot 연동

연동 플로우

1. FastAPI에서 여행 계획 생성 → travel_data.json 저장
2. 사용자 확인 후 "저장" 버튼 클릭
3. FastAPI → Spring Boot API 호출
POST http://52.78.55.147:8080/api/trip-plan/from-fastapi
4. Spring Boot → MySQL DB 저장
5. 저장 결과 반환

데이터 변환 과정

FastAPI (snake_case) → Spring Boot (camelCase)

# TripPlan 모델 (FastAPI)plan_data=plan_response.model_dump(by_alias=True)
# startDate, endDate, dailySchedules... (camelCase)# Spring Boot로 전송 (배포 환경)asyncwithhttpx.AsyncClient() asclient:
response=awaitclient.post(
"http://52.78.55.147:8080/api/trip-plan/from-fastapi",
json=plan_data
)

Spring Boot CreateFromFastAPIDTO:

publicstaticclassCreateFromFastAPIDTO {
privateStringstartDate; // FastAPI에서 "startDate" 전송privateStringendDate;
privateStringbudget;
privateList<DailyScheduleDTO> dailySchedules;
// ...
}

배포 환경 구성

┌─────────────────┐
│ Client App │
│ (Mobile/Web) │
└────────┬────────┘
│
├──────────────────────┬─────────────────────┐
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ FastAPI Server │ │ Spring Boot API │ │ Google │
│ (Docker) │─>│ (AWS EC2) │ │ Gemini API │
│ Port: 8000 │ │ 52.78.55.147 │ └─────────────────┘
└─────────────────┘ └────────┬─────────┘
│ │
▼ ▼
┌─────────────────┐ ┌──────────────────┐
│ travel_data.json│ │ MySQL (RDS) │
│ (로컬 저장) │ │ (영구 저장) │
└─────────────────┘ └──────────────────┘

📂 프로젝트 구조

TripTalk/
├── AI_Chat.py # 메인 FastAPI 애플리케이션
├── main.py # 애플리케이션 엔트리 포인트
├── requirements.txt # Python 패키지 의존성
├── .env # 환경변수 (OpenAI API Key)
├── Dockerfile # Docker 이미지 빌드 파일
├── docker-compose.yml # Docker Compose 설정
├── README.md # 프로젝트 문서
├── data/
│ └── travel_data.json # 여행 계획 JSON 저장소
└── outputs/
└── latest_plan.md # 최신 여행 계획 마크다운

🔧 주요 기술적 특징

1. Pydantic Field Aliases

  • JSON 파일: start_date, end_date (snake_case)
  • Python 모델: startDate, endDate (camelCase)
  • Spring Boot 전송: startDate, endDate (camelCase)
classTripPlan(BaseModel):
startDate: str=Field(..., alias='start_date')
endDate: str=Field(..., alias='end_date')

2. Google Gemini Structured Output

  • Gemini 2.0 Flash의 자연어 기반 JSON 생성
  • Pydantic 모델과 일치하는 구조화된 응답
  • 파싱 에러 최소화

3. 중복 방지 로직

  • 동일 조건 (목적지, 기간, 동행자, 예산, 스타일) 시 기존 데이터 업데이트
  • 다른 조건 시 새 UUID 생성

4. 에러 핸들링

  • Spring Boot 통신 실패 시 재시도
  • Google Gemini API 타임아웃 처리
  • JSON 파싱 에러 복구

📝 커밋 메시지 규칙

타입(Type)설명(Description)
Feat새로운 기능을 추가한 경우
Fix에러·버그를 수정한 경우
DesignCSS 등 UI 디자인을 변경한 경우
HOTFIX급하게 치명적인 에러를 즉시 수정한 경우
Style코드 포맷 변경, 세미콜론 누락 등 로직 변경 없는 스타일 수정
Refactor기능 변화 없이 코드를 리팩토링한 경우
Comment주석 추가 또는 변경
Docs문서를 수정한 경우 (README 등)
Test테스트 코드 추가·변경·리팩토링
Chore기타 변경사항 (빌드, 패키지, 설정 파일 수정 등)
Rename파일·폴더명을 수정하거나 옮기는 경우

예시

git commit -m "Feat: Google Gemini 2.0 Flash 여행 계획 생성 API 추가"
git commit -m "Fix: Spring Boot 연동 시 camelCase 변환 오류 수정"
git commit -m "Docs: README 데이터 모델 섹션 추가"

🔄 버전 히스토리

v1.0.0 (2025-12-12)

  • ✅ Google Gemini 2.0 Flash 기반 여행 계획 생성
  • ✅ Pydantic 모델 기반 데이터 검증
  • ✅ JSON 파일 기반 영구 저장
  • ✅ Spring Boot API 연동 완료
  • ✅ camelCase/snake_case 자동 변환

🤖 TripTalk AI Server - 당신만의 완벽한 여행을 AI가 설계합니다!

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages