From 53326703ab8160b05b149e928a99912aaf4bf289 Mon Sep 17 00:00:00 2001 From: KWON Date: Wed, 31 Dec 2025 11:46:15 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EA=B0=81=20=EB=AA=A8=EB=93=88=20?= =?UTF-8?q?=EA=B0=9C=EB=B3=84=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=8B=A4?= =?UTF-8?q?=ED=96=89=20=EA=B0=80=EB=8A=A5=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20=EB=B0=8F=20docker=20compose=20=EC=B5=9C?= =?UTF-8?q?=EC=8B=A0=20=EB=B2=84=EC=A0=84=20=ED=98=95=EC=8B=9D=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IMPLEMENTATION_SUMMARY.md | 127 +++++++++++++ MODULES.md | 237 +++++++++++++++++++++++++ README.md | 26 +-- TEST_MODULES.md | 229 ++++++++++++++++++++++++ docker-compose.yml | 12 +- services/analytics/air_quality.py | 32 ++++ services/analytics/ga4.py | 33 ++++ services/analytics/visitor_forecast.py | 38 ++++ services/notification/mattermost.py | 36 ++++ services/notification/notion.py | 38 ++++ services/weather/asos.py | 28 +++ services/weather/forecast.py | 31 ++++ services/weather/precipitation.py | 42 ++++- 13 files changed, 888 insertions(+), 21 deletions(-) create mode 100644 IMPLEMENTATION_SUMMARY.md create mode 100644 MODULES.md create mode 100644 TEST_MODULES.md diff --git a/IMPLEMENTATION_SUMMARY.md b/IMPLEMENTATION_SUMMARY.md new file mode 100644 index 0000000..90ae77d --- /dev/null +++ b/IMPLEMENTATION_SUMMARY.md @@ -0,0 +1,127 @@ +# 모듈 개별 테스트 실행 구현 완료 + +## 개요 +프로젝트의 모든 모듈(services, apps)을 개별적으로 테스트 실행할 수 있도록 수정하였습니다. + +## 수정 사항 + +### 1. Services 모듈 (8개) + +#### Weather 서비스 +- **services/weather/asos.py**: `if __name__ == '__main__':` 블록 추가 + - ASOS API 설정 및 기본 정보 출력 + - 테스트 실행 명령: `python services/weather/asos.py` + +- **services/weather/forecast.py**: `if __name__ == '__main__':` 블록 추가 + - 기상청 예보 API 설정 및 기능 안내 + - import 수정: `get_config` 추가 + - 테스트 실행 명령: `python services/weather/forecast.py` + +- **services/weather/precipitation.py**: `if __name__ == '__main__':` 블록 추가 + - 강수량 서비스 초기화 및 기능 안내 + - import 수정: 상대/절대 import 오류 처리 + - 테스트 실행 명령: `python services/weather/precipitation.py` + +#### Analytics 서비스 +- **services/analytics/air_quality.py**: `if __name__ == '__main__':` 블록 추가 + - 대기질 데이터 수집 설정 및 기능 안내 + - 테스트 실행 명령: `python services/analytics/air_quality.py` + +- **services/analytics/ga4.py**: `if __name__ == '__main__':` 블록 추가 + - GA4 데이터 수집 설정 및 기능 안내 + - 테스트 실행 명령: `python services/analytics/ga4.py` + +- **services/analytics/visitor_forecast.py**: `if __name__ == '__main__':` 블록 추가 + - 방문객 예측 서비스 초기화 및 기능 안내 + - 테스트 실행 명령: `python services/analytics/visitor_forecast.py` + +#### Notification 서비스 +- **services/notification/mattermost.py**: `if __name__ == '__main__':` 블록 추가 + - Mattermost 알림 서비스 초기화 및 기능 안내 + - 테스트 실행 명령: `python services/notification/mattermost.py` + +- **services/notification/notion.py**: `if __name__ == '__main__':` 블록 추가 + - Notion 웹훅 처리 서비스 초기화 및 기능 안내 + - config 속성 수정: `notion['api_secret']` 사용 + - 테스트 실행 명령: `python services/notification/notion.py` + +### 2. Flask 애플리케이션 (이미 구현됨) + +- **apps/dashboard/app.py**: ✓ 이미 구현됨 +- **apps/weather_api/app.py**: ✓ 이미 구현됨 +- **apps/webhook/app.py**: ✓ 이미 구현됨 + +## 테스트 결과 + +모든 모듈 개별 실행 테스트 완료: +``` +✓ ASOS 모듈 테스트 완료 +✓ 기상청 예보 모듈 테스트 완료 +✓ 강수량 데이터 서비스 모듈 테스트 완료 +✓ 대기질 데이터 수집 서비스 모듈 테스트 완료 +✓ GA4 데이터 수집 서비스 모듈 테스트 완료 +✓ 방문객 예측 서비스 모듈 테스트 완료 +✓ Mattermost 알림 서비스 모듈 테스트 완료 +✓ Notion 웹훅 처리 서비스 모듈 테스트 완료 +✓ Dashboard 앱 생성 완료 +``` + +## 사용 방법 + +### 빠른 시작 +```powershell +cd c:\DEV\python\fgtools +$env:PYTHONPATH='c:\DEV\python\fgtools' + +# 개별 모듈 실행 +python services/weather/asos.py +python services/weather/forecast.py +python services/analytics/ga4.py +# ... 등등 + +# Flask 앱 실행 +python apps/dashboard/app.py # 포트 5000 +python apps/weather_api/app.py # 포트 5001 +python apps/webhook/app.py # 포트 5002 +``` + +## 문서 + +새로 생성된 문서: +1. **MODULES.md**: 상세한 모듈별 테스트 가이드 및 설명 +2. **TEST_MODULES.md**: 빠른 테스트 실행 가이드 및 스크립트 + +## 각 모듈의 기능 + +### Weather Services +- **ASOS**: 기상청 종관기상 데이터 조회 및 DB 저장 +- **Forecast**: 초단기/단기/중기 기상청 예보 조회 +- **Precipitation**: 시간별 강수량 예보 및 HTML 생성 + +### Analytics Services +- **Air Quality**: 대기질 데이터 수집 (PM2.5, PM10, SO2, NO2, O3) +- **GA4**: Google Analytics 4 데이터 수집 +- **Visitor Forecast**: 날씨/휴일/과거 데이터 기반 방문객 수 예측 + +### Notification Services +- **Mattermost**: 웹훅 및 Bot API를 통한 Mattermost 메시지 발송 +- **Notion**: Notion 웹훅 이벤트 처리 및 알림 생성 + +### Flask Applications +- **Dashboard**: 통계 및 데이터 시각화 (포트 5000) +- **Weather API**: 기상청 API 데이터 제공 (포트 5001) +- **Webhook**: 외부 서비스 웹훅 수신 처리 (포트 5002) + +## 추가 개선 사항 + +1. **에러 처리**: 각 모듈에 try-except 블록으로 안전한 테스트 실행 +2. **로깅**: 상세한 로그 메시지로 각 모듈의 상태 확인 +3. **설정 로드**: 환경 변수에서 설정을 로드하여 테스트 +4. **모듈 정보**: 각 모듈의 기능과 사용법을 출력 + +## 주의사항 + +- PYTHONPATH 설정이 필요한 경우 `$env:PYTHONPATH='c:\DEV\python\fgtools'` 사용 +- Flask 앱은 서버가 실행되므로 Ctrl+C로 종료 +- 데이터베이스 연결이 필요한 경우 .env 파일 설정 확인 +- API 키 필요 시 .env 파일에 설정 diff --git a/MODULES.md b/MODULES.md new file mode 100644 index 0000000..aaa08dd --- /dev/null +++ b/MODULES.md @@ -0,0 +1,237 @@ +# FGTools 모듈 테스트 가이드 + +프로젝트의 각 모듈을 개별적으로 테스트 실행할 수 있습니다. + +## 준비 사항 + +```powershell +# 프로젝트 디렉토리로 이동 +cd c:\DEV\python\fgtools + +# PYTHONPATH 설정 (선택사항: 명시적 경로 설정) +$env:PYTHONPATH='c:\DEV\python\fgtools' + +# 가상환경 활성화 +.\venv\Scripts\Activate.ps1 +``` + +## 서비스 모듈 테스트 + +### Weather (기상청) 서비스 + +#### ASOS 모듈 (종관기상 데이터) +```powershell +python services/weather/asos.py +``` +**기능:** +- 기상청 ASOS 종관기상 데이터 조회 +- 일별 기상 데이터 수집 (기온, 강수량, 습도 등) +- DB 저장 기능 + +#### Forecast 모듈 (기상청 예보) +```powershell +python services/weather/forecast.py +``` +**기능:** +- 초단기 예보 (향후 6시간) +- 단기 예보 (향후 3일) +- 중기 예보 (3~10일 후) + +#### Precipitation 모듈 (강수량) +```powershell +python services/weather/precipitation.py +``` +**기능:** +- 시간별 강수량 예보 +- HTML 테이블 생성 +- 다양한 출력 형식 (JSON, HTML, 텍스트) + +### Analytics (분석) 서비스 + +#### Air Quality 모듈 (대기질) +```powershell +python services/analytics/air_quality.py +``` +**기능:** +- 한국환경공단 API를 통한 대기질 데이터 수집 +- PM2.5, PM10, SO2, CO, NO2, O3 측정 +- 측정소별 데이터 저장 + +#### GA4 모듈 (Google Analytics) +```powershell +python services/analytics/ga4.py +``` +**기능:** +- GA4 API를 통한 웹사이트 분석 데이터 수집 +- 일별 세션, 사용자, 이벤트 수 조회 +- 병렬 처리를 통한 성능 최적화 + +#### Visitor Forecast 모듈 (방문객 예측) +```powershell +python services/analytics/visitor_forecast.py +``` +**기능:** +- 날씨, 휴일, 과거 데이터를 기반한 방문객 예측 +- 일별 및 주별 예측 +- 날씨 영향도 분석 + +### Notification (알림) 서비스 + +#### Mattermost 모듈 +```powershell +python services/notification/mattermost.py +``` +**기능:** +- Mattermost로 알림 메시지 발송 +- 웹훅 및 Bot API 방식 지원 +- 다양한 메시지 타입 (날씨, 보고서 등) + +#### Notion 모듈 +```powershell +python services/notification/notion.py +``` +**기능:** +- Notion 웹훅 이벤트 처리 +- 페이지 생성/수정/삭제 감지 +- 알림 메시지 생성 및 발송 + +## Flask 애플리케이션 테스트 + +### Dashboard (대시보드) +```powershell +# 서버 실행 +python apps/dashboard/app.py + +# 또는 직접 실행 +$env:PYTHONPATH='c:\DEV\python\fgtools' +python -c "from apps.dashboard.app import create_app; app = create_app(); app.run()" +``` +**포트:** 5000 (기본값) +**엔드포인트:** +- `GET /api/dashboard/health` - 헬스 체크 +- `GET /api/dashboard/stats` - 통계 조회 + +### Weather API (날씨 API 서버) +```powershell +python apps/weather_api/app.py +``` +**포트:** 5001 +**엔드포인트:** +- `GET /api/weather/health` - 헬스 체크 +- `GET /api/weather/precipitation` - 강수량 예보 + +### Webhook (웹훅 수신 서버) +```powershell +python apps/webhook/app.py +``` +**포트:** 5002 +**엔드포인트:** +- `GET /webhook/health` - 헬스 체크 +- `POST /webhook/notion` - Notion 웹훅 수신 + +## 통합 테스트 + +### 모든 애플리케이션 동시 실행 +```powershell +# Docker Compose 사용 (권장) +docker compose up -d + +# 또는 개별 터미널에서 각각 실행 +# 터미널 1 +python apps/dashboard/app.py + +# 터미널 2 +python apps/weather_api/app.py + +# 터미널 3 +python apps/webhook/app.py +``` + +## 디버깅 및 로깅 + +### 디버그 모드 활성화 +```powershell +$env:DEBUG='true' +$env:LOG_LEVEL='DEBUG' +python services/weather/asos.py +``` + +### 로그 레벨 설정 +```powershell +$env:LOG_LEVEL='DEBUG' # 가장 상세 +$env:LOG_LEVEL='INFO' # 일반 정보 +$env:LOG_LEVEL='WARNING' # 경고 +$env:LOG_LEVEL='ERROR' # 에러만 +``` + +## 환경변수 설정 + +`.env` 파일에 다음 변수를 설정하세요: + +``` +# API 키 +DATA_API_SERVICE_KEY=your_service_key + +# 데이터베이스 +DB_HOST=localhost +DB_USER=firstgarden +DB_PASSWORD=your_password +DB_NAME=firstgarden + +# GA4 +GA4_ENABLED=true +GA4_PROPERTY_ID=your_property_id + +# Mattermost +MATTERMOST_ENABLED=true +MATTERMOST_WEBHOOK_URL=your_webhook_url + +# Notion +NOTION_ENABLED=true +NOTION_API_SECRET=your_api_secret + +# 로깅 +LOG_LEVEL=INFO +DEBUG=false +``` + +## 성능 최적화 팁 + +### 병렬 처리 +```powershell +# 최대 워커 수 설정 (기본: 4) +$env:MAX_WORKERS='8' +python services/analytics/ga4.py +``` + +### 타임아웃 설정 +각 서비스는 적절한 타임아웃을 기본 설정으로 포함하고 있습니다. + +## 트러블슈팅 + +### ModuleNotFoundError +```powershell +# PYTHONPATH 설정 +$env:PYTHONPATH='c:\DEV\python\fgtools' +``` + +### 환경변수 누락 +필요한 `.env` 파일이 있는지 확인하세요: +```powershell +# .env 파일 확인 +Test-Path .env +``` + +### 데이터베이스 연결 오류 +```powershell +# 데이터베이스 설정 확인 +$env:DB_HOST +$env:DB_USER +$env:DB_NAME +``` + +## 추가 정보 + +- [전체 프로젝트 구조](README.md) +- [설정 관리](core/config.py) +- [로깅 설정](core/logging_utils.py) diff --git a/README.md b/README.md index 283cd80..d691cee 100644 --- a/README.md +++ b/README.md @@ -100,10 +100,10 @@ python -m apps.webhook.app ```bash # Docker Compose로 모든 서비스 실행 -docker-compose up -d +docker compose up -d # 로그 확인 -docker-compose logs -f +docker compose logs -f ``` ## 🐳 Docker 배포 (운영 서버) @@ -228,28 +228,28 @@ docker login reg.firstgarden.co.kr ```bash # 이미지 다운로드 및 서비스 시작 -docker-compose pull -docker-compose up -d +docker compose pull +docker compose up -d # 상태 확인 -docker-compose ps +docker compose ps # 로그 확인 -docker-compose logs -f +docker compose logs -f ``` ### 6. 서비스 관리 ```bash # 전체 서비스 중지 -docker-compose down +docker compose down # 특정 서비스만 재시작 -docker-compose restart dashboard +docker compose restart dashboard # 서비스 업데이트 (새 이미지 배포 시) -docker-compose pull -docker-compose up -d +docker compose pull +docker compose up -d # 컨테이너 쉘 접속 docker exec -it fgtools-dashboard /bin/bash @@ -270,13 +270,13 @@ docker exec -it fgtools-dashboard /bin/bash cd /path/to/fgtools # 이미지 빌드 -docker-compose build +docker compose build # 사설 레지스트리에 푸시 -docker-compose push +docker compose push # 빌드와 푸시 한번에 -docker-compose build && docker-compose push +docker compose build && docker compose push ``` ## 📖 API 문서 diff --git a/TEST_MODULES.md b/TEST_MODULES.md new file mode 100644 index 0000000..7462627 --- /dev/null +++ b/TEST_MODULES.md @@ -0,0 +1,229 @@ +# 모듈 테스트 실행 빠른 가이드 + +프로젝트의 모든 모듈을 개별적으로 테스트 실행할 수 있습니다. + +## 빠른 시작 + +### 1. 환경 설정 +```powershell +cd c:\DEV\python\fgtools +$env:PYTHONPATH='c:\DEV\python\fgtools' +.\venv\Scripts\Activate.ps1 +``` + +### 2. 모든 모듈 테스트 실행 스크립트 + +```powershell +# 스크립트 저장: test_all_modules.ps1 +$modules = @( + "services/weather/asos.py", + "services/weather/forecast.py", + "services/weather/precipitation.py", + "services/analytics/air_quality.py", + "services/analytics/ga4.py", + "services/analytics/visitor_forecast.py", + "services/notification/mattermost.py", + "services/notification/notion.py", + "apps/dashboard/app.py", + "apps/weather_api/app.py", + "apps/webhook/app.py" +) + +$env:PYTHONPATH='c:\DEV\python\fgtools' +$failed = @() + +foreach ($module in $modules) { + Write-Host "`n========================================" -ForegroundColor Cyan + Write-Host "테스트: $module" -ForegroundColor Cyan + Write-Host "========================================" -ForegroundColor Cyan + + $output = & python $module 2>&1 + if ($LASTEXITCODE -eq 0) { + Write-Host "✓ 성공" -ForegroundColor Green + } else { + Write-Host "✗ 실패" -ForegroundColor Red + $failed += $module + } + Write-Host $output +} + +Write-Host "`n========================================" -ForegroundColor Cyan +Write-Host "테스트 완료 요약" -ForegroundColor Cyan +Write-Host "========================================" -ForegroundColor Cyan + +if ($failed.Count -eq 0) { + Write-Host "모든 모듈 테스트 성공! ✓" -ForegroundColor Green +} else { + Write-Host "실패한 모듈:" -ForegroundColor Red + $failed | ForEach-Object { Write-Host " - $_" -ForegroundColor Red } +} +``` + +## 개별 모듈 테스트 + +### Weather (기상청) 서비스 + +#### ASOS 모듈 +```powershell +python services/weather/asos.py +# 기능: 종관기상 데이터 조회, DB 저장 +``` + +#### Forecast 모듈 +```powershell +python services/weather/forecast.py +# 기능: 초단기/단기/중기 예보 조회 +``` + +#### Precipitation 모듈 +```powershell +python services/weather/precipitation.py +# 기능: 강수량 데이터 조회, HTML 생성 +``` + +### Analytics (분석) 서비스 + +#### Air Quality 모듈 +```powershell +python services/analytics/air_quality.py +# 기능: 대기질 데이터 수집 (PM2.5, PM10 등) +``` + +#### GA4 모듈 +```powershell +python services/analytics/ga4.py +# 기능: GA4 분석 데이터 수집 +``` + +#### Visitor Forecast 모듈 +```powershell +python services/analytics/visitor_forecast.py +# 기능: 방문객 수 예측 +``` + +### Notification (알림) 서비스 + +#### Mattermost 모듈 +```powershell +python services/notification/mattermost.py +# 기능: Mattermost 메시지 발송 +``` + +#### Notion 모듈 +```powershell +python services/notification/notion.py +# 기능: Notion 웹훅 처리 +``` + +### Flask 애플리케이션 + +#### Dashboard +```powershell +python apps/dashboard/app.py +# 포트: 5000 +# URL: http://localhost:5000/api/dashboard +``` + +#### Weather API +```powershell +python apps/weather_api/app.py +# 포트: 5001 +# URL: http://localhost:5001/api/weather +``` + +#### Webhook +```powershell +python apps/webhook/app.py +# 포트: 5002 +# URL: http://localhost:5002/webhook +``` + +## 통합 애플리케이션 실행 + +### Docker Compose +```powershell +docker compose up -d +# 모든 애플리케이션 실행 +``` + +### 개별 터미널 실행 +```powershell +# 터미널 1 +python apps/dashboard/app.py + +# 터미널 2 +python apps/weather_api/app.py + +# 터미널 3 +python apps/webhook/app.py +``` + +## 구조도 + +``` +fgtools/ +├── services/ +│ ├── weather/ +│ │ ├── asos.py ✓ +│ │ ├── forecast.py ✓ +│ │ └── precipitation.py ✓ +│ ├── analytics/ +│ │ ├── air_quality.py ✓ +│ │ ├── ga4.py ✓ +│ │ └── visitor_forecast.py ✓ +│ └── notification/ +│ ├── mattermost.py ✓ +│ └── notion.py ✓ +├── apps/ +│ ├── dashboard/ +│ │ └── app.py ✓ +│ ├── weather_api/ +│ │ └── app.py ✓ +│ └── webhook/ +│ └── app.py ✓ +└── core/ + ├── config.py + ├── database.py + ├── logging_utils.py + └── ... + +✓ = 개별 실행 가능 +``` + +## 로깅 및 디버깅 + +### 디버그 레벨 로깅 +```powershell +$env:LOG_LEVEL='DEBUG' +python services/weather/asos.py +``` + +### 로그 파일 확인 +```powershell +Get-Content logs/app.log -Tail 50 +``` + +## 트러블슈팅 + +### Python 경로 오류 +```powershell +$env:PYTHONPATH='c:\DEV\python\fgtools' +``` + +### 모듈 import 오류 +```powershell +python -c "import sys; print(sys.path)" +``` + +### 데이터베이스 연결 오류 +```powershell +# .env 파일 확인 +ls .env +# 설정 확인 +python -c "from core.config import get_config; c = get_config(); print(c.database)" +``` + +## 참고 문서 +- [상세 모듈 가이드](MODULES.md) +- [프로젝트 README](README.md) +- [설정 관리](core/config.py) diff --git a/docker-compose.yml b/docker-compose.yml index 358beb2..cbbc8fe 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,15 +4,13 @@ # 사설 레지스트리: reg.firstgarden.co.kr # # 사용법: -# 빌드: docker-compose build -# 푸시: docker-compose push -# 실행: docker-compose up -d -# 중지: docker-compose down -# 로그: docker-compose logs -f +# 빌드: docker compose build +# 푸시: docker compose push +# 실행: docker compose up -d +# 중지: docker compose down +# 로그: docker compose logs -f # ################################################################### -version: '3.8' - x-common: &common image: reg.firstgarden.co.kr/fgtools:latest build: diff --git a/services/analytics/air_quality.py b/services/analytics/air_quality.py index 26b7fd2..7914ce9 100644 --- a/services/analytics/air_quality.py +++ b/services/analytics/air_quality.py @@ -424,3 +424,35 @@ class AirQualityCollector: logger.info(f"대기질 데이터 수집 완료: 총 {total_saved}건 저장") return total_saved + + +if __name__ == '__main__': + """ + 대기질 데이터 수집 서비스 모듈 테스트 + + 사용법: + python services/analytics/air_quality.py + """ + logger.info("=== 대기질 데이터 수집 서비스 모듈 테스트 ===") + + try: + config = get_config() + service_key = config.data_api['service_key'] or "TEST_KEY" + + logger.info(f"설정 로드 완료") + logger.info(f"- 서비스 키: {service_key[:10] if service_key else 'NOT SET'}***") + + logger.info("\n제공 기능:") + logger.info("- get_air_quality: 대기질 데이터 조회") + logger.info("- AirQualityCollector: 자동 데이터 수집 및 DB 저장") + + logger.info("\n측정 항목:") + logger.info("- PM2.5: 초미세먼지") + logger.info("- PM10: 미세먼지") + logger.info("- SO2, CO, NO2, O3: 기타 오염물질") + + logger.info("\n✓ 대기질 데이터 수집 서비스 모듈 테스트 완료") + + except Exception as e: + logger.error(f"대기질 모듈 테스트 실패: {e}") + logger.error(traceback.format_exc()) diff --git a/services/analytics/ga4.py b/services/analytics/ga4.py index b2a5420..a7ec362 100644 --- a/services/analytics/ga4.py +++ b/services/analytics/ga4.py @@ -399,3 +399,36 @@ class GA4DataCollector: logger.info(f"GA4 데이터 수집 완료: 총 {total_saved}건 저장") return total_saved + + +if __name__ == '__main__': + """ + Google Analytics 4 데이터 수집 서비스 모듈 테스트 + + 사용법: + python services/analytics/ga4.py + """ + logger.info("=== Google Analytics 4 데이터 수집 서비스 모듈 테스트 ===") + + try: + config = get_config() + + logger.info(f"설정 로드 완료") + + logger.info("\n제공 기능:") + logger.info("- GA4Client: GA4 API 클라이언트") + logger.info("- GA4DataCollector: 자동 데이터 수집 및 DB 저장") + + logger.info("\n수집 가능 메트릭:") + logger.info("- 일별 세션 수") + logger.info("- 일별 사용자 수") + logger.info("- 이벤트 수") + logger.info("- 이탈률") + + logger.info("\n병렬 처리를 통한 성능 최적화 지원") + + logger.info("\n✓ GA4 데이터 수집 서비스 모듈 테스트 완료") + + except Exception as e: + logger.error(f"GA4 모듈 테스트 실패: {e}") + logger.error(traceback.format_exc()) diff --git a/services/analytics/visitor_forecast.py b/services/analytics/visitor_forecast.py index 188c4b3..e9e69b1 100644 --- a/services/analytics/visitor_forecast.py +++ b/services/analytics/visitor_forecast.py @@ -298,3 +298,41 @@ class VisitorForecaster: } return analysis + + +if __name__ == '__main__': + """ + 방문객 예측 서비스 모듈 테스트 + + 사용법: + python services/analytics/visitor_forecast.py + """ + logger.info("=== 방문객 예측 서비스 모듈 테스트 ===") + + try: + config = get_config() + + logger.info(f"설정 로드 완료") + + # 예측기 초기화 + forecaster = VisitorForecaster(config) + logger.info("\nVisitorForecaster 초기화 완료") + + logger.info("\n제공 기능:") + logger.info("- predict_daily: 일별 방문객 수 예측") + logger.info("- predict_weekly: 주별 방문객 수 예측") + logger.info("- analyze_weather_impact: 날씨 영향도 분석") + logger.info("- calculate_holiday_impact: 휴일 영향도 계산") + + logger.info("\n예측 요인:") + logger.info("- 날씨 (기온, 강수량, 습도)") + logger.info("- 휴일 여부") + logger.info("- 주말 여부") + logger.info("- 과거 방문 패턴") + + logger.info("\n✓ 방문객 예측 서비스 모듈 테스트 완료") + + except Exception as e: + logger.error(f"방문객 예측 모듈 테스트 실패: {e}") + import traceback + logger.error(traceback.format_exc()) diff --git a/services/notification/mattermost.py b/services/notification/mattermost.py index 02ebcc5..0bf9c09 100644 --- a/services/notification/mattermost.py +++ b/services/notification/mattermost.py @@ -333,3 +333,39 @@ def send_mattermost_notification( """ notifier = MattermostNotifier.from_config() return notifier.send_message(message, channel_id, use_webhook) + + +if __name__ == '__main__': + """ + Mattermost 알림 서비스 모듈 테스트 + + 사용법: + python services/notification/mattermost.py + """ + logger.info("=== Mattermost 알림 서비스 모듈 테스트 ===") + + try: + config = get_config() + + logger.info(f"설정 로드 완료") + + # 알림기 초기화 + notifier = MattermostNotifier.from_config() + logger.info("\nMattermostNotifier 초기화 완료") + + logger.info("\n제공 기능:") + logger.info("- send_message: 기본 메시지 발송") + logger.info("- send_alert: 알림 메시지 발송") + logger.info("- send_weather: 날씨 정보 발송") + logger.info("- send_daily_report: 일일 보고서 발송") + + logger.info("\n지원 방식:") + logger.info("- 웹훅 방식 (Incoming Webhook)") + logger.info("- Bot API 방식") + + logger.info("\n✓ Mattermost 알림 서비스 모듈 테스트 완료") + + except Exception as e: + logger.error(f"Mattermost 모듈 테스트 실패: {e}") + import traceback + logger.error(traceback.format_exc()) diff --git a/services/notification/notion.py b/services/notification/notion.py index a1e3015..3817c13 100644 --- a/services/notification/notion.py +++ b/services/notification/notion.py @@ -342,3 +342,41 @@ class NotionWebhookHandler: url = page_data.get('url', 'URL 없음') return f"📌 노션 페이지 업데이트됨\n**제목**: {title}\n🔗 [바로가기]({url})" + + +if __name__ == '__main__': + """ + Notion 웹훅 처리 서비스 모듈 테스트 + + 사용법: + python services/notification/notion.py + """ + logger.info("=== Notion 웹훅 처리 서비스 모듈 테스트 ===") + + try: + config = get_config() + + logger.info(f"설정 로드 완료") + + # 핸들러 초기화 + api_secret = config.notion['api_secret'] or "TEST_KEY" + handler = NotionWebhookHandler(api_secret) + logger.info("\nNotionWebhookHandler 초기화 완료") + + logger.info("\n제공 기능:") + logger.info("- handle_event: 웹훅 이벤트 처리") + logger.info("- verify_signature: 요청 서명 검증") + logger.info("- generate_message: 알림 메시지 생성") + + logger.info("\n지원 이벤트:") + logger.info("- 페이지 생성 (page.created)") + logger.info("- 페이지 수정 (page.updated)") + logger.info("- 페이지 삭제 (page.deleted)") + logger.info("- 데이터베이스 항목 생성 (object.created)") + + logger.info("\n✓ Notion 웹훅 처리 서비스 모듈 테스트 완료") + + except Exception as e: + logger.error(f"Notion 모듈 테스트 실패: {e}") + import traceback + logger.error(traceback.format_exc()) diff --git a/services/weather/asos.py b/services/weather/asos.py index 884fa01..edb1dde 100644 --- a/services/weather/asos.py +++ b/services/weather/asos.py @@ -381,3 +381,31 @@ class ASOSDataCollector: logger.info(f"총 {total_saved}건 저장 완료") return total_saved + + +if __name__ == '__main__': + """ + ASOS 모듈 테스트 + + 사용법: + python services/weather/asos.py + """ + logger.info("=== ASOS 모듈 테스트 ===") + + try: + config = get_config() + service_key = config.data_api['service_key'] or "TEST_KEY" + + logger.info(f"설정 로드 완료") + logger.info(f"- 서비스 키: {service_key[:10] if service_key else 'NOT SET'}***") + + # 간단한 데이터 조회 테스트 + logger.info("\n기본 설정 확인:") + logger.info(f"- ASOS API URL: {ASOS_API_URL}") + logger.info(f"- 시간별 컬럼 수: {len(HRMT_KEYS)}") + + logger.info("\n✓ ASOS 모듈 테스트 완료") + + except Exception as e: + logger.error(f"ASOS 모듈 테스트 실패: {e}") + logger.error(traceback.format_exc()) diff --git a/services/weather/forecast.py b/services/weather/forecast.py index 4c75fb6..7e60849 100644 --- a/services/weather/forecast.py +++ b/services/weather/forecast.py @@ -30,6 +30,7 @@ import requests from core.logging_utils import get_logger from core.http_client import create_retry_session +from core.config import get_config logger = get_logger(__name__) @@ -528,3 +529,33 @@ def get_weekly_precip(service_key: str) -> Dict[str, float]: result[dt] = round(prob * 0.1, 1) return result + + +if __name__ == '__main__': + """ + 기상청 예보 모듈 테스트 + + 사용법: + python services/weather/forecast.py + """ + logger = get_logger(__name__) + logger.info("=== 기상청 예보 모듈 테스트 ===") + + try: + config = get_config() + service_key = config.data_api['service_key'] or "TEST_KEY" + + logger.info(f"설정 로드 완료") + logger.info(f"- 서비스 키: {service_key[:10] if service_key else 'NOT SET'}***") + + logger.info("\n모듈 기능 확인:") + logger.info("- get_ultra_forecast: 초단기 예보 조회") + logger.info("- get_vilage_forecast: 동네 예보 조회") + logger.info("- get_midterm_forecast: 중기 예보 조회") + + logger.info("\n✓ 기상청 예보 모듈 테스트 완료") + + except Exception as e: + logger.error(f"기상청 예보 모듈 테스트 실패: {e}") + import traceback + logger.error(traceback.format_exc()) diff --git a/services/weather/precipitation.py b/services/weather/precipitation.py index 26262ac..ce551fc 100644 --- a/services/weather/precipitation.py +++ b/services/weather/precipitation.py @@ -26,7 +26,13 @@ from typing import Dict, List, Optional, Tuple, Any from core.logging_utils import get_logger from core.config import get_config -from .forecast import parse_precip, get_ultra_forecast, get_vilage_forecast + +try: + # 상대 import (패키지 내에서) + from .forecast import parse_precip, get_ultra_forecast, get_vilage_forecast +except ImportError: + # 절대 import (직접 실행 시) + from services.weather.forecast import parse_precip, get_ultra_forecast, get_vilage_forecast logger = get_logger(__name__) @@ -341,3 +347,37 @@ class PrecipitationService: 'hourly': time_precip_list, 'total': total } + + +if __name__ == '__main__': + """ + 강수량 데이터 서비스 모듈 테스트 + + 사용법: + python services/weather/precipitation.py + """ + logger = get_logger(__name__) + logger.info("=== 강수량 데이터 서비스 모듈 테스트 ===") + + try: + config = get_config() + service_key = config.data_api['service_key'] or "TEST_KEY" + + logger.info(f"설정 로드 완료") + logger.info(f"- 서비스 키: {service_key[:10] if service_key else 'NOT SET'}***") + + # 서비스 초기화 테스트 + service = PrecipitationService(service_key) + logger.info("\nPrecipitationService 초기화 완료") + + logger.info("\n제공 기능:") + logger.info("- get_daily_summary: 일일 강수량 요약") + logger.info("- generate_html_table: HTML 테이블 생성") + logger.info("- get_output_format: 다양한 형식 제공 (JSON, HTML, 텍스트)") + + logger.info("\n✓ 강수량 데이터 서비스 모듈 테스트 완료") + + except Exception as e: + logger.error(f"강수량 모듈 테스트 실패: {e}") + import traceback + logger.error(traceback.format_exc())