Files
static/DEVELOPMENT.md
KWON 7121f250bc feat: Flask 애플리케이션 모듈화 및 웹 대시보드 구현
- Flask Blueprint 아키텍처로 전환 (dashboard, upload, backup, status)
- app.py 681줄  95줄로 축소 (86% 감소)
- HTML 템플릿 모듈화 (base.html + 기능별 templates)
- CSS/JS 파일 분리 (common + 기능별 파일)
- 대시보드 기능 추가 (통계, 주간 예보, 방문객 추이)
- 파일 업로드 웹 인터페이스 구현
- 백업/복구 관리 UI 구현
- Docker 배포 환경 개선
- .gitignore 업데이트 (uploads, backups, cache 등)
2025-12-26 17:31:37 +09:00

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