- Flask Blueprint 아키텍처로 전환 (dashboard, upload, backup, status) - app.py 681줄 95줄로 축소 (86% 감소) - HTML 템플릿 모듈화 (base.html + 기능별 templates) - CSS/JS 파일 분리 (common + 기능별 파일) - 대시보드 기능 추가 (통계, 주간 예보, 방문객 추이) - 파일 업로드 웹 인터페이스 구현 - 백업/복구 관리 UI 구현 - Docker 배포 환경 개선 - .gitignore 업데이트 (uploads, backups, cache 등)
8.4 KiB
8.4 KiB
개발자 가이드 (Developer Guide)
이 문서는 First Garden Static Analysis Service에 기여하거나 개발하고자 하는 개발자를 위한 가이드입니다.
개발 환경 설정
1. 저장소 클론
git clone https://git.siane.kr/firstgarden/static.git
cd static
2. Python 가상환경 생성
# Python 3.11 이상 필수
python3.11 -m venv venv
# 가상환경 활성화
# Linux/macOS
source venv/bin/activate
# Windows
.\venv\Scripts\activate
3. 의존성 설치
pip install --upgrade pip setuptools wheel
pip install -r requirements.txt
# 개발 도구 추가 설치
pip install pytest pytest-cov black flake8 mypy
4. 환경 변수 설정
cp .env.example .env
# .env 파일을 편집하여 로컬 DB 정보 입력
5. 로컬 데이터베이스 설정
# Docker로 MariaDB 실행 (기존 DB가 없는 경우)
docker run --name fg-static-db \
-e MYSQL_ROOT_PASSWORD=rootpassword \
-e MYSQL_DATABASE=firstgarden \
-e MYSQL_USER=firstgarden \
-e MYSQL_PASSWORD=Fg9576861! \
-p 3306:3306 \
mariadb:11.2-jammy
코드 스타일
PEP 8 준수
# 코드 포매팅
black lib/ conf/ daily_run.py
# 린트 검사
flake8 lib/ conf/ daily_run.py --max-line-length=100
# 타입 검사
mypy lib/ conf/ --ignore-missing-imports
명명 규칙
- 함수/변수:
snake_case - 클래스:
PascalCase - 상수:
UPPER_CASE - 비공개 함수:
_leading_underscore
문서화
모든 함수에 docstring 작성:
def fetch_data(start_date, end_date, **kwargs):
"""
데이터 조회 함수
Args:
start_date (datetime.date): 시작 날짜
end_date (datetime.date): 종료 날짜
**kwargs: 추가 매개변수
Returns:
pd.DataFrame: 조회된 데이터
Raises:
ValueError: 유효하지 않은 날짜 범위
DatabaseError: DB 연결 실패
"""
...
로깅 사용법
from lib.common import setup_logging
# 로거 생성
logger = setup_logging('module_name', 'INFO')
# 로그 출력
logger.info('정보 메시지')
logger.warning('경고 메시지')
logger.error('에러 메시지', exc_info=True) # 스택 트레이스 포함
logger.debug('디버그 메시지')
데이터베이스 작업
세션 관리
from conf.db import DBSession
# 권장: 컨텍스트 매니저 사용
with DBSession() as session:
result = session.execute(select(some_table))
# 자동으로 커밋 또는 롤백
# 또는 기존 방식
session = db.get_session()
try:
result = session.execute(select(some_table))
session.commit()
finally:
session.close()
쿼리 작성
from sqlalchemy import select, and_, func
from conf import db_schema
# 데이터 조회
session = db.get_session()
stmt = select(
db_schema.weather.c.date,
db_schema.weather.c.maxTa
).where(
and_(
db_schema.weather.c.date >= '2025-01-01',
db_schema.weather.c.stnId == 99
)
)
result = session.execute(stmt).fetchall()
API 데이터 수집
기본 패턴
import requests
from lib.common import setup_logging, retry_on_exception
logger = setup_logging(__name__, 'INFO')
@retry_on_exception(max_retries=3, delay=1.0, backoff=2.0)
def fetch_api_data(url, params):
"""API 데이터 수집"""
try:
response = requests.get(url, params=params, timeout=20)
response.raise_for_status()
data = response.json()
logger.info(f"API 데이터 수집 완료: {len(data)} 건")
return data
except requests.exceptions.RequestException as e:
logger.error(f"API 요청 실패: {e}")
raise
테스트 작성
단위 테스트
# 테스트 디렉토리 생성
mkdir tests
# 테스트 파일 작성
cat > tests/test_common.py << 'EOF'
import pytest
from lib.common import load_config
def test_load_config():
config = load_config()
assert config is not None
assert 'database' in config
assert 'DATA_API' in config
def test_load_config_invalid_path():
with pytest.raises(FileNotFoundError):
load_config('/invalid/path.yaml')
EOF
# 테스트 실행
pytest tests/ -v
pytest tests/ --cov=lib --cov=conf
통합 테스트
# tests/test_integration.py
import pytest
from conf.db import DBSession
from lib.weekly_visitor_forecast_prophet import load_data
def test_load_data_integration():
"""DB에서 데이터 로드 테스트"""
with DBSession() as session:
from datetime import date, timedelta
start_date = date.today() - timedelta(days=30)
end_date = date.today()
df = load_data(session, start_date, end_date)
assert len(df) > 0
assert 'pos_qty' in df.columns
모듈 개발 체크리스트
새로운 모듈을 추가할 때 다음을 확인하세요:
- 모든 함수에 docstring 작성
- PEP 8 코드 스타일 준수
- 로깅 추가 (info, warning, error)
- 에러 처리 구현
- 단위 테스트 작성
requirements.txt업데이트- README.md 업데이트
- CHANGELOG.md 업데이트
Git 워크플로우
기본 브랜치
main: 배포 준비 브랜치develop: 개발 메인 브랜치feature/*: 기능 개발bugfix/*: 버그 수정
커밋 메시지 포맷
[타입] 간단한 설명
더 자세한 설명 (선택사항)
연관 이슈: #123
타입:
feat: 새로운 기능fix: 버그 수정docs: 문서화refactor: 코드 리팩토링test: 테스트 추가chore: 설정 변경
브랜치 생성 및 병합
# 브랜치 생성
git checkout develop
git pull origin develop
git checkout -b feature/새로운기능
# 커밋
git add .
git commit -m "[feat] 새로운 기능 추가"
# 푸시
git push origin feature/새로운기능
# Merge Request/Pull Request 생성 후 코드 리뷰
CI/CD 파이프라인
GitHub Actions (예상 설정)
# .github/workflows/test.yml
name: Test
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
with:
python-version: '3.11'
- run: pip install -r requirements.txt
- run: pytest tests/ --cov=lib --cov=conf
문제 해결
일반적인 개발 문제
Q: DB 연결 실패
# DB 상태 확인
docker ps | grep mariadb
# DB 접속 확인
mysql -h localhost -u firstgarden -p firstgarden
# conf/config.yaml에서 DB 정보 확인
Q: 패키지 설치 오류
# 캐시 초기화
pip cache purge
# 의존성 재설치
pip install -r requirements.txt --force-reinstall
Q: 포트 이미 사용 중
# 기존 컨테이너 제거
docker-compose down -v
# 포트 사용 프로세스 확인
lsof -i :3306
성능 프로파일링
실행 시간 측정
import time
from lib.common import setup_logging
logger = setup_logging(__name__)
start = time.time()
# 코드 실행
elapsed = time.time() - start
logger.info(f"실행 시간: {elapsed:.2f}초")
메모리 프로파일링
# memory_profiler 설치
pip install memory-profiler
# 스크립트 실행
python -m memory_profiler script.py
배포 준비
프로덕션 체크리스트
- 모든 테스트 통과
- 코드 리뷰 완료
- 버전 번호 업데이트 (CHANGELOG.md)
- 환경 변수 검증
- 데이터베이스 마이그레이션 확인
- Docker 이미지 빌드 및 테스트
- 보안 취약점 검사
- 성능 벤치마크
유용한 명령어
# 개발 모드로 실행
PYTHONUNBUFFERED=1 python daily_run.py
# 로그 모니터링
tail -f logs/daily_run.log
# Docker 컨테이너 로그
docker-compose logs -f fg-static
# 데이터베이스 접속
docker-compose exec mariadb mysql -u firstgarden -p firstgarden
# 파이썬 인터랙티브 셸
python -c "import sys; sys.path.insert(0, '.'); from conf import db; print(db.load_config())"
참고 자료
작성일: 2025-12-26 마지막 업데이트: 2025-12-26