334 lines
8.4 KiB
Markdown
334 lines
8.4 KiB
Markdown
|
|
# FlaskFarm 프로젝트 구조 및 흐름 분석
|
||
|
|
|
||
|
|
이 프로젝트는 **Flask 기반의 플러그인 확장 가능한 웹 프레임워크**입니다.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 1. 전체 아키텍처
|
||
|
|
|
||
|
|
```
|
||
|
|
main.py (진입점)
|
||
|
|
↓
|
||
|
|
framework.initialize()
|
||
|
|
↓
|
||
|
|
├─ Framework 초기화 (Singleton)
|
||
|
|
├─ Flask App 생성
|
||
|
|
├─ 시스템 모듈 로딩
|
||
|
|
└─ 플러그인 동적 로딩
|
||
|
|
↓
|
||
|
|
Flask Server 시작
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 2. 핵심 컴포넌트
|
||
|
|
|
||
|
|
### A. Framework (lib/framework/)
|
||
|
|
|
||
|
|
**싱글톤 패턴**으로 구현된 핵심 프레임워크:
|
||
|
|
|
||
|
|
- **init_main.py**: Framework 클래스 - 모든 컴포넌트의 중앙 관리자
|
||
|
|
|
||
|
|
- Flask, Celery, SQLAlchemy, SocketIO, Scheduler, Redis 초기화
|
||
|
|
- 로깅 시스템 설정
|
||
|
|
- config.yaml 기반 설정 관리
|
||
|
|
|
||
|
|
- **init_plugin.py**: PluginManager - 플러그인 동적 로딩
|
||
|
|
|
||
|
|
- `data/plugins/` 폴더에서 플러그인 자동 발견
|
||
|
|
- `path_dev` 설정으로 개발 플러그인 경로 지원
|
||
|
|
- 플러그인 화이트리스트/블랙리스트 필터링
|
||
|
|
|
||
|
|
- **scheduler.py**: APScheduler 래퍼
|
||
|
|
- Interval/Cron 기반 스케줄링
|
||
|
|
- Job 인스턴스 생명주기 관리
|
||
|
|
- gevent/threading 모드 지원
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### B. Plugin 시스템 (lib/plugin/)
|
||
|
|
|
||
|
|
**플러그인 구조** (3계층):
|
||
|
|
|
||
|
|
```
|
||
|
|
Plugin
|
||
|
|
└─ Module (기능 그룹)
|
||
|
|
└─ Page (세부 페이지)
|
||
|
|
```
|
||
|
|
|
||
|
|
**주요 파일**:
|
||
|
|
|
||
|
|
- **create_plugin.py**: PluginBase 클래스
|
||
|
|
|
||
|
|
- `info.yaml`에서 메타데이터 로드
|
||
|
|
- Blueprint 등록 (URL prefix: `/플러그인명/`)
|
||
|
|
- DB 바인딩 (SQLite per plugin)
|
||
|
|
- ModelSetting으로 설정 관리
|
||
|
|
|
||
|
|
- **logic_module_base.py**: PluginModuleBase
|
||
|
|
- 모듈별 라우팅 (menu, ajax, command, api)
|
||
|
|
- 스케줄러 통합
|
||
|
|
- 페이지 리스트 관리
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### C. System 모듈 (lib/system/)
|
||
|
|
|
||
|
|
내장 시스템 기능:
|
||
|
|
|
||
|
|
- **mod_setting**: 일반 설정, 웹, 인증, 알림 등
|
||
|
|
- **mod_plugin**: 플러그인 관리 UI
|
||
|
|
- **mod_log**: 전체 로그 뷰어
|
||
|
|
- **mod_tool**: Command, 업로드, Python REPL 등
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 3. 실행 흐름
|
||
|
|
|
||
|
|
### 시작 단계
|
||
|
|
|
||
|
|
1. **main.py** 실행
|
||
|
|
|
||
|
|
- gevent monkey patching
|
||
|
|
- Celery 환경변수 설정
|
||
|
|
- `framework.initialize()` 호출
|
||
|
|
|
||
|
|
2. **Framework 초기화**
|
||
|
|
|
||
|
|
```python
|
||
|
|
F = Framework.get_instance() # Singleton
|
||
|
|
F.__initialize()
|
||
|
|
```
|
||
|
|
|
||
|
|
- config.yaml 로드
|
||
|
|
- 로깅 시스템 구성
|
||
|
|
- Flask app 생성
|
||
|
|
- DB 초기화 (system + 각 플러그인)
|
||
|
|
- Scheduler, SocketIO, Celery 설정
|
||
|
|
|
||
|
|
3. **시스템 모듈 로딩**
|
||
|
|
|
||
|
|
```python
|
||
|
|
F.initialize_system()
|
||
|
|
```
|
||
|
|
|
||
|
|
- system 패키지에서 기본 모듈 로드
|
||
|
|
- 라우트 등록
|
||
|
|
|
||
|
|
4. **플러그인 로딩**
|
||
|
|
|
||
|
|
```python
|
||
|
|
F.initialize_plugin()
|
||
|
|
```
|
||
|
|
|
||
|
|
- PluginManager가 플러그인 목록 수집
|
||
|
|
- 각 플러그인 info.yaml 파싱
|
||
|
|
- setup.py에서 Plugin 인스턴스 생성
|
||
|
|
- 모듈/페이지 초기화
|
||
|
|
- DB 마이그레이션
|
||
|
|
- 자동시작 설정된 스케줄러 등록
|
||
|
|
|
||
|
|
5. **서버 시작**
|
||
|
|
```python
|
||
|
|
frame.start()
|
||
|
|
```
|
||
|
|
- SocketIO 서버 실행 (gevent 또는 threading 모드)
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 4. 플러그인 개발 패턴
|
||
|
|
|
||
|
|
플러그인 구조 예시 (ffmpeg):
|
||
|
|
|
||
|
|
```
|
||
|
|
ffmpeg/
|
||
|
|
├── info.yaml # 메타데이터
|
||
|
|
├── __init__.py # 플러그인 엔트리포인트
|
||
|
|
├── setup.py # P = create_plugin_instance(setting)
|
||
|
|
├── mod_download.py # Module 구현
|
||
|
|
└── templates/ # Jinja2 템플릿
|
||
|
|
```
|
||
|
|
|
||
|
|
**라우팅 자동 생성**:
|
||
|
|
|
||
|
|
- `/ffmpeg/download/list` → `mod_download.process_menu('list')`
|
||
|
|
- `/ffmpeg/download/ajax/<sub>` → `mod_download.process_ajax(sub)`
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 5. 데이터 흐름
|
||
|
|
|
||
|
|
### 설정 관리
|
||
|
|
|
||
|
|
```
|
||
|
|
config.yaml (글로벌)
|
||
|
|
↓
|
||
|
|
Framework.config (딕셔너리)
|
||
|
|
↓
|
||
|
|
각 플러그인의 ModelSetting (DB 저장)
|
||
|
|
```
|
||
|
|
|
||
|
|
### 데이터 저장
|
||
|
|
|
||
|
|
```
|
||
|
|
path_data/
|
||
|
|
├── db/
|
||
|
|
│ ├── system.db # 시스템 설정
|
||
|
|
│ ├── ffmpeg.db # 플러그인별 DB
|
||
|
|
│ └── ...
|
||
|
|
├── log/ # 로테이션 로그
|
||
|
|
├── plugins/ # 설치된 플러그인
|
||
|
|
└── tmp/ # 임시 파일
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 6. 비동기 작업 (Celery)
|
||
|
|
|
||
|
|
- Redis를 브로커로 사용
|
||
|
|
- 각 모듈에서 `@celery.task` 데코레이터로 정의
|
||
|
|
- `plugin_load_celery()` 훅으로 초기화
|
||
|
|
- 백그라운드 작업 처리 (다운로드, 인코딩 등)
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 7. 스케줄링
|
||
|
|
|
||
|
|
```python
|
||
|
|
Job 인스턴스 생성
|
||
|
|
↓
|
||
|
|
Scheduler.add_job_instance()
|
||
|
|
↓
|
||
|
|
APScheduler에 등록 (Interval/Cron)
|
||
|
|
↓
|
||
|
|
자동 실행 (랜덤 딜레이 포함)
|
||
|
|
```
|
||
|
|
|
||
|
|
- 모듈별 `auto_start` 설정
|
||
|
|
- DB 자동 삭제 기능 (`db_auto_delete`)
|
||
|
|
- 실시간 상태 모니터링
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 8. 주요 기능
|
||
|
|
|
||
|
|
✅ **플러그인 시스템**: 동적 로드/언로드
|
||
|
|
✅ **멀티 DB**: SQLite per plugin
|
||
|
|
✅ **실시간 통신**: SocketIO
|
||
|
|
✅ **스케줄링**: Interval/Cron 작업
|
||
|
|
✅ **인증**: Flask-Login
|
||
|
|
✅ **알림**: 텔레그램, 디스코드 지원
|
||
|
|
✅ **로그 뷰어**: 웹 기반 실시간 로그
|
||
|
|
✅ **파일 관리**: 업로드, 다운로드, 편집 (flaskcode)
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 9. 설정 우선순위
|
||
|
|
|
||
|
|
1. 환경변수 (REDIS_PORT 등)
|
||
|
|
2. config.yaml
|
||
|
|
3. DB의 SystemModelSetting
|
||
|
|
4. 플러그인별 ModelSetting
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 10. 디렉토리 구조
|
||
|
|
|
||
|
|
```
|
||
|
|
flaskfarm/
|
||
|
|
├── main.py # 애플리케이션 진입점
|
||
|
|
├── config.yaml # 글로벌 설정
|
||
|
|
├── lib/ # 핵심 라이브러리
|
||
|
|
│ ├── framework/ # 프레임워크 코어
|
||
|
|
│ │ ├── init_main.py # Framework 클래스 (Singleton)
|
||
|
|
│ │ ├── init_plugin.py # PluginManager
|
||
|
|
│ │ ├── init_route.py # 글로벌 라우팅
|
||
|
|
│ │ ├── scheduler.py # 스케줄러
|
||
|
|
│ │ └── ...
|
||
|
|
│ ├── plugin/ # 플러그인 베이스
|
||
|
|
│ │ ├── create_plugin.py # PluginBase 클래스
|
||
|
|
│ │ ├── logic_module_base.py
|
||
|
|
│ │ ├── route.py # 플러그인 라우팅
|
||
|
|
│ │ └── ...
|
||
|
|
│ ├── system/ # 시스템 모듈
|
||
|
|
│ │ ├── mod_setting.py # 설정 관리
|
||
|
|
│ │ ├── mod_plugin.py # 플러그인 관리
|
||
|
|
│ │ ├── mod_log.py # 로그 뷰어
|
||
|
|
│ │ └── ...
|
||
|
|
│ ├── support/ # 공통 유틸리티
|
||
|
|
│ ├── tool/ # 도구 모음
|
||
|
|
│ └── tool_base/ # 기본 도구
|
||
|
|
├── data/ # 데이터 디렉토리
|
||
|
|
│ ├── db/ # SQLite 데이터베이스
|
||
|
|
│ ├── log/ # 로그 파일
|
||
|
|
│ ├── plugins/ # 설치된 플러그인
|
||
|
|
│ └── tmp/ # 임시 파일
|
||
|
|
└── files/ # 템플릿 파일
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 11. 플러그인 생명주기
|
||
|
|
|
||
|
|
```
|
||
|
|
1. 발견 (Discovery)
|
||
|
|
- PluginManager.get_plugin_name_list()
|
||
|
|
- data/plugins/ 또는 path_dev 스캔
|
||
|
|
|
||
|
|
2. 로딩 (Loading)
|
||
|
|
- info.yaml 파싱
|
||
|
|
- setup.py의 create_plugin_instance() 호출
|
||
|
|
- Blueprint 등록
|
||
|
|
- DB 바인딩
|
||
|
|
|
||
|
|
3. 초기화 (Initialization)
|
||
|
|
- plugin_load() 호출
|
||
|
|
- DB 마이그레이션
|
||
|
|
- 스케줄러 등록
|
||
|
|
- Celery 작업 등록
|
||
|
|
|
||
|
|
4. 실행 (Runtime)
|
||
|
|
- HTTP 요청 처리
|
||
|
|
- 스케줄 작업 실행
|
||
|
|
- SocketIO 이벤트 처리
|
||
|
|
|
||
|
|
5. 언로딩 (Unloading)
|
||
|
|
- plugin_unload() 호출
|
||
|
|
- 스케줄러 작업 제거
|
||
|
|
- 리소스 정리
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 12. 주요 API 엔드포인트
|
||
|
|
|
||
|
|
### 글로벌 엔드포인트
|
||
|
|
|
||
|
|
- `/` → 홈 (시스템 대시보드로 리다이렉트)
|
||
|
|
- `/system/setting` → 시스템 설정
|
||
|
|
- `/system/plugin` → 플러그인 관리
|
||
|
|
- `/system/log` → 전체 로그
|
||
|
|
- `/global/ajax/<sub>` → 공통 AJAX 처리
|
||
|
|
|
||
|
|
### 플러그인 엔드포인트 (예: ffmpeg)
|
||
|
|
|
||
|
|
- `/ffmpeg/` → 플러그인 홈
|
||
|
|
- `/ffmpeg/<module>/<page>` → 모듈/페이지
|
||
|
|
- `/ffmpeg/<module>/ajax/<sub>` → AJAX 요청
|
||
|
|
- `/ffmpeg/<module>/command` → 커맨드 실행
|
||
|
|
- `/ffmpeg/<module>/api/<sub>` → API 호출
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 결론
|
||
|
|
|
||
|
|
FlaskFarm은 **플러그인을 통한 기능 확장에 최적화**되어 있으며, 각 플러그인이 독립적인 DB, 스케줄러, 라우팅을 가지면서도 중앙 프레임워크의 공통 기능(로깅, 인증, 알림 등)을 활용할 수 있는 **모듈식 웹 애플리케이션 플랫폼**입니다.
|
||
|
|
|
||
|
|
주요 설계 원칙:
|
||
|
|
|
||
|
|
- **플러그인 독립성**: 각 플러그인은 자체 DB와 설정을 가짐
|
||
|
|
- **확장성**: 새로운 플러그인을 쉽게 추가 가능
|
||
|
|
- **중앙 관리**: Framework 싱글톤을 통한 통합 관리
|
||
|
|
- **비동기 처리**: Celery를 통한 백그라운드 작업
|
||
|
|
- **실시간 통신**: SocketIO를 통한 양방향 통신
|