206 lines
5.4 KiB
Python
206 lines
5.4 KiB
Python
# ===================================================================
|
|
# apps/dashboard/app.py
|
|
# 정적 데이터 대시보드 웹 애플리케이션
|
|
# ===================================================================
|
|
# 방문객, 날씨, 대기질, 예측 데이터를 시각화하는 대시보드입니다.
|
|
# Flask Blueprint 기반으로 구현되어 통합 앱에 포함할 수 있습니다.
|
|
# ===================================================================
|
|
"""
|
|
정적 데이터 대시보드 웹 애플리케이션
|
|
|
|
방문객 통계, 날씨 정보, 대기질 데이터 등을 조회하고
|
|
시각화하는 대시보드를 제공합니다.
|
|
|
|
사용 예시:
|
|
from apps.dashboard.app import create_app
|
|
|
|
app = create_app()
|
|
app.run()
|
|
"""
|
|
|
|
import os
|
|
from flask import Flask, Blueprint, jsonify, request, render_template
|
|
from werkzeug.exceptions import HTTPException
|
|
|
|
from core.config import get_config
|
|
from core.logging_utils import get_logger, setup_logging
|
|
from core.database import get_engine, DBSession
|
|
|
|
logger = get_logger(__name__)
|
|
|
|
# Blueprint 생성
|
|
dashboard_bp = Blueprint('dashboard', __name__, url_prefix='/api/dashboard')
|
|
|
|
|
|
@dashboard_bp.route('/health', methods=['GET'])
|
|
def health_check():
|
|
"""
|
|
헬스 체크 엔드포인트
|
|
|
|
Returns:
|
|
상태 정보 JSON
|
|
"""
|
|
return jsonify({
|
|
'status': 'healthy',
|
|
'service': 'dashboard'
|
|
})
|
|
|
|
|
|
@dashboard_bp.route('/stats', methods=['GET'])
|
|
def get_stats():
|
|
"""
|
|
기본 통계 조회
|
|
|
|
Query Parameters:
|
|
start_date: 시작 날짜 (YYYY-MM-DD)
|
|
end_date: 종료 날짜 (YYYY-MM-DD)
|
|
|
|
Returns:
|
|
통계 데이터 JSON
|
|
"""
|
|
start_date = request.args.get('start_date')
|
|
end_date = request.args.get('end_date')
|
|
|
|
# TODO: 실제 통계 조회 구현
|
|
return jsonify({
|
|
'start_date': start_date,
|
|
'end_date': end_date,
|
|
'total_visitors': 0,
|
|
'average_visitors': 0,
|
|
'data': []
|
|
})
|
|
|
|
|
|
@dashboard_bp.route('/weather/forecast', methods=['GET'])
|
|
def get_weather_forecast():
|
|
"""
|
|
날씨 예보 조회
|
|
|
|
Returns:
|
|
날씨 예보 데이터 JSON
|
|
"""
|
|
from services.weather import get_daily_vilage_forecast
|
|
|
|
config = get_config()
|
|
service_key = config.data_api.get('service_key', '')
|
|
|
|
if not service_key:
|
|
return jsonify({'error': 'API 키가 설정되지 않았습니다.'}), 500
|
|
|
|
try:
|
|
forecast = get_daily_vilage_forecast(service_key)
|
|
return jsonify({
|
|
'status': 'success',
|
|
'data': forecast
|
|
})
|
|
except Exception as e:
|
|
logger.error(f"날씨 예보 조회 실패: {e}")
|
|
return jsonify({'error': str(e)}), 500
|
|
|
|
|
|
@dashboard_bp.route('/weather/precipitation', methods=['GET'])
|
|
def get_precipitation():
|
|
"""
|
|
강수량 예보 조회
|
|
|
|
Query Parameters:
|
|
format: 출력 형식 (json, html, text)
|
|
|
|
Returns:
|
|
강수량 데이터
|
|
"""
|
|
from services.weather import PrecipitationService
|
|
|
|
output_format = request.args.get('format', 'json')
|
|
|
|
try:
|
|
service = PrecipitationService()
|
|
data = service.get_precipitation_info(output_format=output_format)
|
|
|
|
if output_format == 'html':
|
|
return data, 200, {'Content-Type': 'text/html; charset=utf-8'}
|
|
elif output_format == 'text':
|
|
return data, 200, {'Content-Type': 'text/plain; charset=utf-8'}
|
|
else:
|
|
return jsonify(data)
|
|
|
|
except Exception as e:
|
|
logger.error(f"강수량 조회 실패: {e}")
|
|
return jsonify({'error': str(e)}), 500
|
|
|
|
|
|
@dashboard_bp.errorhandler(HTTPException)
|
|
def handle_exception(e):
|
|
"""HTTP 예외 핸들러"""
|
|
return jsonify({
|
|
'error': e.description,
|
|
'status_code': e.code
|
|
}), e.code
|
|
|
|
|
|
def create_app(config_override: dict = None) -> Flask:
|
|
"""
|
|
Flask 애플리케이션 팩토리
|
|
|
|
Args:
|
|
config_override: 설정 덮어쓰기 딕셔너리
|
|
|
|
Returns:
|
|
Flask 앱 인스턴스
|
|
"""
|
|
app = Flask(__name__)
|
|
|
|
# 설정 로드
|
|
config = get_config()
|
|
|
|
app.config['SECRET_KEY'] = config.flask.get('secret_key', 'dev-secret')
|
|
app.config['JSON_AS_ASCII'] = False
|
|
|
|
if config_override:
|
|
app.config.update(config_override)
|
|
|
|
# 로깅 설정
|
|
setup_logging('apps.dashboard', level=config.log_level)
|
|
|
|
# Blueprint 등록
|
|
app.register_blueprint(dashboard_bp)
|
|
|
|
# 루트 엔드포인트
|
|
@app.route('/')
|
|
def index():
|
|
return jsonify({
|
|
'name': 'FGTools Dashboard API',
|
|
'version': '1.0.0',
|
|
'endpoints': [
|
|
'/api/dashboard/health',
|
|
'/api/dashboard/stats',
|
|
'/api/dashboard/weather/forecast',
|
|
'/api/dashboard/weather/precipitation',
|
|
]
|
|
})
|
|
|
|
logger.info("Dashboard 앱 초기화 완료")
|
|
return app
|
|
|
|
|
|
def run_server(host: str = '0.0.0.0', port: int = 5000, debug: bool = False):
|
|
"""
|
|
개발 서버 실행
|
|
|
|
Args:
|
|
host: 바인딩 호스트
|
|
port: 포트 번호
|
|
debug: 디버그 모드
|
|
"""
|
|
app = create_app()
|
|
app.run(host=host, port=port, debug=debug)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
config = get_config()
|
|
run_server(
|
|
host=config.flask.get('host', '0.0.0.0'),
|
|
port=config.flask.get('port', 5000),
|
|
debug=config.debug
|
|
)
|