Airflow 웹 UI의 뷰 커스터마이징

Airflow 웹 UI의 뷰 커스터마이징 (Customize view of Apache from Airflow web UI)

Plugin manager를 사용해 Airflow 핵심 UI와 함께 커스텀 UI를 통합하는 방법을 설명하는 문서예요. fastapi_apps, fastapi_root_middlewares, external_views, react_apps 네 가지 객체 참조와, React 플러그인 부트스트랩 툴로 외부 React 앱을 개발·통합하는 방법을 살펴볼게요.

출처: 문서

본문

Airflow에는 Plugin manager를 사용해 핵심 UI와 함께 커스텀 UI를 통합할 수 있는 기능이 있어요.

Plugins는 Airflow 핵심 RestAPI와 통합돼요. 이 플러그인에서는 airflow.plugins_manager.AirflowPlugin 기본 클래스에서 세 가지 객체 참조가 파생돼요. 그것은 fastapi_apps, fastapi_root_middlewares, external_views와 react_apps예요.

  • fastapi_apps를 Airflow 플러그인에서 사용하면 핵심 RestAPI를 확장해 커스텀 정적 파일이나 다른 json/application 응답을 제공하는 추가 엔드포인트를 지원할 수 있어요. 이 객체 참조에서는 FastAPI 애플리케이션과 name, url prefix 같은 메타데이터 정보가 담긴 딕셔너리 목록이 전달돼요.

  • fastapi_root_middlewares를 Airflow 플러그인에서 사용하면 FastAPI 애플리케이션의 루트에 커스텀 미들웨어를 등록할 수 있어요. 이 미들웨어는 핵심 엔드포인트를 포함한 전체 FastAPI 애플리케이션에 커스텀 헤더, 로깅 또는 다른 기능을 추가하는 데 사용할 수 있어요. 이 객체 참조에서는 Middleware 팩토리 객체, 초기화 파라미터, name 같은 메타데이터 정보가 담긴 딕셔너리 목록이 전달돼요.

  • external_views를 Airflow 플러그인에서 사용하면 Airflow UI에서 iframe이나 외부 링크로 렌더링되는 커스텀 뷰를 등록할 수 있어요. 이는 외부 애플리케이션이나 커스텀 대시보드를 Airflow UI에 통합하는 데 유용해요. 이 객체 참조에서는 뷰 이름, href(템플릿 가능), destination, icon과 url_route 같은 선택 파라미터가 담긴 딕셔너리 목록이 전달돼요.

  • react_apps를 Airflow 플러그인에서 사용하면 Airflow UI에서 렌더링할 수 있는 커스텀 React 애플리케이션을 등록할 수 있어요. 이는 커스텀 React 컴포넌트나 애플리케이션을 Airflow UI에 통합하는 데 유용해요. 이 객체 참조에서는 앱 이름, bundle_url(js 자산을 로드할 위치, 템플릿 가능), destination, icon과 url_route 같은 선택 파라미터가 담긴 딕셔너리 목록이 전달돼요.

fastapi_apps, fastapi_root_middlewares, external_views, react_apps를 등록하는 정보와 코드 샘플은 plugin에서 확인할 수 있어요.

Bootstrap Tool로 React 애플리케이션 개발하기 (Developing React Applications with the Bootstrap Tool)

경고 (Warning)

React 애플리케이션은 Airflow 3.1의 새로운 기능으로 실험적(experimental)으로 간주해야 해요. 이 기능은 사용자 피드백과 보고된 오류에 따라 향후 버전에서 경고 없이 변경될 수 있어요. UI와 플러그인 간의 의존성·상태 상호작용이 리팩터링될 수 있으며, 이는 제공된 부트스트랩 예제 프로젝트도 변경시킬 거예요.

이것은 실험적 기능이에요.

Airflow는 React 플러그인 부트스트랩 툴을 제공해 개발자가 외부 React 애플리케이션을 핵심 UI로 빠르게 생성·개발·통합할 수 있게 해요. 이는 Airflow UI를 커스터마이징하는 가장 유연하고 권장되는 방법이에요. 이 툴은 동적 import와 호환되고 호스트 Airflow 애플리케이션과 React 인스턴스를 공유하는 라이브러리로 빌드되는 완전한 React 프로젝트 구조를 생성해요.

새 React 플러그인 프로젝트 만들기 (Creating a New React Plugin Project)

Bootstrap 툴은 dev/react-plugin-tools/에 있고, 새 React 플러그인 프로젝트를 생성하는 간단한 CLI를 제공해요:

# Navigate to the bootstrap tool directory
cd dev/react-plugin-tools

# Create a new plugin project
python bootstrap.py my-awesome-plugin

# Or specify a custom directory
python bootstrap.py my-awesome-plugin --dir /path/to/my-projects/my-awesome-plugin

이것은 Vite, TypeScript, Chakra UI 통합, 그리고 Airflow의 UI와 통합되는 라이브러리로 빌드하는 적절한 구성을 갖춘 완전한 React 프로젝트를 생성해요.

경고 (Warning)

새 React Plugin 프로젝트를 만들 때는 bootstrap 툴을 사용하는 것을 강력히 권장해요. Airflow의 Core UI와의 호환성을 보장하려면 특정 번들링 구성이 필요한데, 프로젝트를 수동으로 설정하면 통합 문제가 생길 수 있어요. 이미 통합하려는 기존 React 프로젝트가 있다면, 참고용으로 bootstrap 툴 코드와 생성된 빌드 구성 파일을 살펴볼 수 있어요. React와 React-DOM은 호스트 애플리케이션과 공유되는 의존성이며 호환 가능한 버전이 필요해요.

React 개발 워크플로우 (React Development Workflow)

프로젝트가 생성되면 프로젝트 디렉토리의 README.md 파일에서 다음을 포함한 완전한 개발 지침을 참고하세요:

  • 사용 가능한 개발 스크립트 (pnpm dev, pnpm build 등)
  • 프로젝트 구조 설명
  • 핫 리로드가 있는 개발 워크플로우
  • 프로덕션용 빌드
  • 흔한 React 개발 문제 트러블슈팅

생성된 프로젝트는 필요한 모든 도구가 사전 구성되어 있고 Airflow의 UI 개발 패턴을 따르고 있어요.

Airflow와 통합하기 (Integrating with Airflow)

React 애플리케이션을 Airflow와 통합하려면 다음을 해야 해요:

  1. 빌드된 자산을 제공 (Serve the built assets) — 자신의 인프라에서 하거나 fastapi_apps를 사용해 Airflow 내에서 직접 할 수 있어요.
  2. React 앱을 등록 (Register the React app)react_apps 플러그인 구성을 사용해요.

예시 플러그인 구현 (Example Plugin Implementation)

React 애플리케이션을 제공하는 Airflow 플러그인을 만들어요:

from pathlib import Path
from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles
import mimetypes

from airflow.plugins_manager import AirflowPlugin

# Ensure proper MIME types for cjs files
mimetypes.add_type("application/javascript", ".cjs")

# Create FastAPI app to serve static files
app = FastAPI()

# Mount your React app's dist folder
react_app_directory = Path(__file__).parent.joinpath("my-awesome-plugin", "dist")
app.mount(
    "/my-react-app",
    StaticFiles(directory=react_app_directory, html=True),
    name="my_react_app_static",
)

class MyReactPlugin(AirflowPlugin):
    name = "My React Plugin"

    # Serve static files
    fastapi_apps = [
        {
            "app": app,
            "url_prefix": "/my-plugin",
            "name": "My Plugin Static Server",
        }
    ]

    # Register React application
    react_apps = [
        {
            "name": "My Awesome React App",
            "url_route": "my-awesome-app",
            "bundle_url": "https://airflow-domain/my-plugin/my-react-app/main.umd.cjs",
            "destination": "nav",
        }
    ]

플러그인 구성 옵션 (Plugin Configuration Options)

React 앱은 몇 가지 구성 옵션을 지원해요. 자세한 내용은 plugin을 참고하세요.

통합 모범 사례 (Integration Best Practices)

생성된 템플릿은 Airflow 통합에 이 모범 사례를 따르고 있어요:

  1. 외부 의존성 (External Dependencies) — React와 공통 라이브러리는 호스트 애플리케이션과의 충돌을 피하기 위해 외부로 표시돼요.
  2. 전역 명명 (Global Naming) — 일관성을 위해 표준화된 전역 이름(AirflowPlugin)을 사용해요.
  3. 라이브러리 빌드 (Library Build) — 동적 import를 위한 적절한 외부화와 함께 UMD 라이브러리로 구성돼요.
  4. MIME 타입 (MIME Types) — FastAPI가 기본적으로 .cjs 파일을 평문 텍스트로 제공하므로, .cjs 파일에 대한 적절한 JavaScript MIME 타입 처리를 해요.

배포 전략 (Deployment Strategies)

외부 호스팅 (External Hosting)

자산을 외부 인프라에서 호스팅할 수도 있어요:

react_apps = [
    {
        "name": "My External App",
        "url_route": "my-external-app",
        "bundle_url": "https://my-cdn.com/main.umd.cjs",
        "destination": "nav",
    }
]

통합 문제 트러블슈팅 (Troubleshooting Integration Issues)

흔한 통합 문제와 해결책:

  • MIME 타입 문제mimetypes.add_type("application/javascript", ".cjs")를 사용해 .js.cjs 파일이 올바른 MIME 타입으로 제공되도록 해요.
  • 컴포넌트가 로드되지 않음 — bundle URL에 접근 가능하고 예상 형식과 일치하는지 확인해요.
  • React 개발 문제 — 프로젝트와 함께 생성된 README.md 파일에서 React 특유의 개발 문제 트러블슈팅을 참고하세요.

Airflow 2 플러그인 지원 (Support for Airflow 2 plugins)

Airflow 2 플러그인은 몇 가지 제한과 함께 여전히 지원돼요. 그러한 플러그인에 대한 자세한 정보는 Airflow 2 문서에서 찾을 수 있어요.

blueprints를 통한 Rest 엔드포인트 추가는 여전히 지원되고, 그 엔드포인트들은 WSGI Middleware를 통해 FastAPI 애플리케이션에 통합되어 /pluginsv2 아래에서 접근할 수 있어요.

Airflow 2를 통한 Flask-AppBuilder 뷰(appbuilder_views) 추가는 자체 iframe에서 여전히 지원돼요.

AF3 핵심 UI(예: 기본 템플릿 확장)를 확장하는 것은 불가능하지만, auth manager의 추가 메뉴 항목이 핵심 UI 보안 탭에 추가되고 그 href는 iframe에서 렌더링돼요. 이것이 fab provider가 Airflow 3 UI에 users, roles, actions, resources, permissions 커스텀 뷰를 통합하는 방식이에요.

Airflow 3 플러그인은 전체 react 앱에 대한 UI 커스터마이징을 허용하도록 개선될 거예요. 가능하면 플러그인을 Airflow 3 플러그인으로 업그레이드하는 것을 권장해요. 그때까지 임시적이거나 커스텀한 요구에는 Middleware를 사용해 핵심 UI index 요청에 커스텀 javascript나 css를 주입할 수 있어요.

더 알아보기 (Learn more)