เดชเดฐเต€เด•เตเดทเดฃเดพเดคเตเดฎเด• API เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต เดŽเดฏเตผเดซเตเดฒเต‹เดฏเดฟเตฝ เด’เดฐเต DAG เดŸเตเดฐเดฟเด—เตผ เดŽเด™เตเด™เดจเต† เดจเดฟเตผเดฎเตเดฎเดฟเด•เตเด•เดพเด‚

เดžเด™เตเด™เดณเตเดŸเต† เดตเดฟเดฆเตเดฏเดพเดญเตเดฏเดพเดธ เดชเดฐเดฟเดชเดพเดŸเดฟเด•เตพ เดคเดฏเตเดฏเดพเดฑเดพเด•เตเด•เตเดจเตเดจเดคเดฟเตฝ, เดšเดฟเดฒ เด‰เดชเด•เดฐเดฃเด™เตเด™เดณเตเดฎเดพเดฏเดฟ เดชเตเดฐเดตเตผเดคเตเดคเดฟเด•เตเด•เตเดฎเตเดชเต‹เตพ เดžเด™เตเด™เตพ เด‡เดŸเดฏเตเด•เตเด•เดฟเดŸเต† เดฌเตเดฆเตเดงเดฟเดฎเตเดŸเตเดŸเตเด•เตพ เดจเต‡เดฐเดฟเดŸเตเดจเตเดจเต. เดžเด™เตเด™เตพ เด…เดตเดฐเต† เด…เดญเดฟเดฎเตเด–เต€เด•เดฐเดฟเด•เตเด•เตเดจเตเดจ เดจเดฟเดฎเดฟเดทเดคเตเดคเดฟเตฝ, เดˆ เดชเตเดฐเดถเตเดจเดคเตเดคเต† เดจเต‡เดฐเดฟเดŸเดพเตป เดธเดนเดพเดฏเดฟเด•เตเด•เตเดจเตเดจ เดฎเดคเดฟเดฏเดพเดฏ เดกเต‹เด•เตเดฏเตเดฎเต†เดจเตเดฑเต‡เดทเดจเตเด•เดณเตเด‚ เดฒเต‡เด–เดจเด™เตเด™เดณเตเด‚ เดŽเดฒเตเดฒเดพเดฏเตเดชเตเดชเต‹เดดเตเด‚ เด‡เดฒเตเดฒ.

เด‰เดฆเดพเดนเดฐเดฃเดคเตเดคเดฟเดจเต, 2015-เตฝ, เดฌเดฟเด—เต เดกเดพเดฑเตเดฑเดพ เดธเตเดชเต†เดทเตเดฏเดฒเดฟเดธเตเดฑเตเดฑเต เดชเตเดฐเต‹เด—เตเดฐเดพเดฎเดฟเตฝ เด’เดฐเต‡เดธเดฎเดฏเด‚ 35 เด‰เดชเดฏเต‹เด•เตเดคเดพเด•เตเด•เตพเด•เตเด•เดพเดฏเดฟ เดžเด™เตเด™เตพ เดธเตเดชเดพเตผเด•เตเด•เดฟเดจเตŠเดชเตเดชเด‚ เดนเดกเต‚เดชเตเดชเต เด•เตเดฒเดธเตเดฑเตเดฑเตผ เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต. YARN เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต เด…เดคเตเดคเดฐเดฎเตŠเดฐเต เด‰เดชเดฏเต‹เด•เตเดคเตƒ เด•เต‡เดธเดฟเดจเดพเดฏเดฟ เด‡เดคเต เดŽเด™เตเด™เดจเต† เดคเดฏเตเดฏเดพเดฑเดพเด•เตเด•เดฃเดฎเต†เดจเตเดจเต เดตเตเดฏเด•เตเดคเดฎเดฒเตเดฒ. เดคเตฝเดซเดฒเดฎเดพเดฏเดฟ, เด…เดตเตผ เดธเตเดตเดจเตเดคเดฎเดพเดฏเดฟ เดชเดพเดค เด•เดฃเตเดŸเต†เดคเตเดคเดฟ, เดจเดŸเดจเตเดจเต เดนเดฌเตเดฐเต†เดฏเดฟเดฒเต† เดชเต‹เดธเตเดฑเตเดฑเต เด•เต‚เดŸเดพเดคเต† เด…เดตเดคเดฐเดฟเดชเตเดชเดฟเดšเตเดšเต เดฎเต‹เดธเตเด•เต‹ เดธเตเดชเดพเตผเด•เตเด•เต เดฎเต€เดฑเตเดฑเดชเตเดชเต.

เดšเดฐเดฟเดคเตเดฐเดพเดคเต€เดคเด•เดพเดฒเด‚

เด‡เดคเตเดคเดตเดฃ เดจเดฎเตเดฎเตพ เดธเด‚เดธเดพเดฐเดฟเด•เตเด•เตเดจเตเดจเดคเต เดฎเดฑเตเดฑเตŠเดฐเต เดชเดฐเดฟเดชเดพเดŸเดฟเดฏเต† เด•เตเดฑเดฟเดšเตเดšเดพเดฃเต - เดกเดพเดฑเตเดฑ เดŽเดžเตเดšเดฟเดจเต€เดฏเตผ. เดžเด™เตเด™เดณเตเดŸเต† เดชเด™เตเด•เดพเดณเดฟเด•เตพ เด…เดคเดฟเตฝ เดฐเดฃเตเดŸเต เดคเดฐเด‚ เดตเดพเดธเตเดคเตเดตเดฟเดฆเตเดฏเด•เตพ เดจเดฟเตผเดฎเตเดฎเดฟเด•เตเด•เตเดจเตเดจเต: เดฒเดพเด‚เดกเดฏเตเด‚ เด•เดชเตเดชเดฏเตเด‚. เดฒเดพเด‚เดกเตเดฌ เด†เตผเด•เตเด•เดฟเดŸเต†เด•เตเดšเดฑเดฟเตฝ, เดŽเดšเตเดšเตเดกเดฟเดŽเดซเตเดŽเดธเดฟเตฝ เดจเดฟเดจเตเดจเต เด•เตเดฒเดฟเด•เตเด•เตเดนเต—เดธเดฟเดฒเต‡เด•เตเด•เต เดฒเต‹เด—เตเด•เตพ เด•เตˆเดฎเดพเดฑเตเดจเตเดจเดคเดฟเดจเต เดฌเดพเดšเตเดšเต เดชเตเดฐเต‹เดธเดธเตเดธเดฟเด‚เด—เดฟเดจเตเดฑเต† เดญเดพเด—เดฎเดพเดฏเดฟ เดŽเดฏเตผเดซเตเดฒเต‹ เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เตเดจเตเดจเต.

เดŽเดฒเตเดฒเดพเด‚ เดชเตŠเดคเตเดตเต† เดจเดฒเตเดฒเดคเดพเดฃเต. เด…เดตเตผ เดชเตˆเดชเตเดชเต เดฒเตˆเดจเตเด•เตพ เดจเดฟเตผเดฎเตเดฎเดฟเด•เตเด•เดŸเตเดŸเต†. เดŽเดจเตเดจเดฟเดฐเตเดจเตเดจเดพเดฒเตเด‚, เด’เดฐเต "เดชเด•เตเดทเต‡" เด‰เดฃเตเดŸเต: เดžเด™เตเด™เดณเตเดŸเต† เดŽเดฒเตเดฒเดพ เดชเตเดฐเต‹เด—เตเดฐเดพเดฎเตเด•เดณเตเด‚ เดชเด เดจ เดชเตเดฐเด•เตเดฐเดฟเดฏเดฏเตเดŸเต† เด•เดพเดฐเตเดฏเดคเตเดคเดฟเตฝ เดธเดพเด™เตเด•เต‡เดคเดฟเด•เดฎเดพเดฏเดฟ เดชเตเดฐเต‹เด—เดฎเดฟเดšเตเดšเดตเดฏเดพเดฃเต. เดฒเดพเดฌเต เดชเดฐเดฟเดถเต‹เดงเดฟเด•เตเด•เดพเตป, เดžเด™เตเด™เตพ เด“เดŸเตเดŸเต‹เดฎเดพเดฑเตเดฑเดฟเด•เต เดšเต†เด•เตเด•เดฑเตเด•เตพ เด‰เดชเดฏเต‹เด—เดฟเด•เตเด•เตเดจเตเดจเต: เดชเด™เตเด•เต†เดŸเตเด•เตเด•เตเดจเตเดจเดฏเดพเตพ เดคเดจเตเดฑเต† เดธเตเดตเด•เดพเดฐเตเดฏ เด…เด•เตเด•เต—เดฃเตเดŸเดฟเดฒเต‡เด•เตเด•เต เดชเต‹เด•เต‡เดฃเตเดŸเดคเตเดฃเตเดŸเต, "เดšเต†เด•เตเด•เต" เดฌเดŸเตเดŸเดฃเดฟเตฝ เด•เตเดฒเดฟเด•เตเด•เต เดšเต†เดฏเตเดฏเตเด•, เด•เตเดฑเดšเตเดšเต เดธเดฎเดฏเดคเตเดคเดฟเดจเต เดถเต‡เดทเด‚ เด…เดตเตป เดšเต†เดฏเตเดคเดคเดฟเดจเต†เด•เตเด•เตเดฑเดฟเดšเตเดšเตเดณเตเดณ เดšเดฟเดฒ เดตเดฟเดชเตเดฒเต€เด•เตƒเดค เดซเต€เดกเตเดฌเดพเด•เตเด•เต เด…เดตเตป เด•เดพเดฃเตเดจเตเดจเต. เดˆ เด˜เดŸเตเดŸเดคเตเดคเดฟเดฒเดพเดฃเต เดจเดฎเตเดฎเตพ เดจเดฎเตเดฎเตเดŸเต† เดชเตเดฐเดถเตเดจเดคเตเดคเต† เดธเดฎเต€เดชเดฟเด•เตเด•เดพเตป เดคเตเดŸเด™เตเด™เตเดจเตเดจเดคเต.

เดˆ เดฒเดพเดฌเต เดชเดฐเดฟเดถเต‹เดงเดฟเด•เตเด•เตเดจเตเดจเดคเต เด‡เดจเดฟเดชเตเดชเดฑเดฏเตเดจเตเดจ เดฐเต€เดคเดฟเดฏเดฟเตฝ เด•เตเดฐเดฎเต€เด•เดฐเดฟเดšเตเดšเดฟเดฐเดฟเด•เตเด•เตเดจเตเดจเต: เดชเด™เตเด•เดพเดณเดฟเดฏเตเดŸเต† เด•เดพเดซเตเด•เดฏเดฟเดฒเต‡เด•เตเด•เต เดžเด™เตเด™เตพ เด’เดฐเต เดจเดฟเดฏเดจเตเดคเตเดฐเดฃ เดกเดพเดฑเตเดฑ เดชเดพเด•เตเด•เดฑเตเดฑเต เด…เดฏเดฏเตเด•เตเด•เตเดจเตเดจเต, เดคเตเดŸเตผเดจเตเดจเต Gobblin เดˆ เดกเดพเดฑเตเดฑเดพ เดชเดพเด•เตเด•เดฑเตเดฑเต HDFS-เดฒเต‡เด•เตเด•เต เดฎเดพเดฑเตเดฑเตเดจเตเดจเต, เดคเตเดŸเตผเดจเตเดจเต Airflow เดˆ เดกเดพเดฑเตเดฑเดพ เดชเดพเด•เตเด•เดฑเตเดฑเต เดŽเดŸเตเดคเตเดคเต ClickHouse-เตฝ เด‡เดŸเตเดจเตเดจเต. เดŽเดฏเตผเดซเตเดฒเต‹ เด‡เดคเต เดคเดคเตเดธเดฎเดฏเด‚ เดšเต†เดฏเตเดฏเต‡เดฃเตเดŸเดคเดฟเดฒเตเดฒ เดŽเดจเตเดจเดคเดพเดฃเต, เด‡เดคเต เดทเต†เดกเตเดฏเต‚เดณเดฟเตฝ เดšเต†เดฏเตเดฏเตเดจเตเดจเต: เด“เดฐเต‹ 15 เดฎเดฟเดจเดฟเดฑเตเดฑเดฟเดฒเตเด‚ เด’เดฐเต เด•เต‚เดŸเตเดŸเด‚ เดซเดฏเดฒเตเด•เตพ เดŽเดŸเตเดคเตเดคเต เด…เดต เด…เดชเตโ€Œเดฒเต‹เดกเต เดšเต†เดฏเตเดฏเตเดจเตเดจเต.

เดšเต†เด•เตเด•เตผ เด‡เดตเดฟเดŸเต†เดฏเตเด‚ เด‡เดชเตเดชเต‹เดณเตเด‚ เดชเตเดฐเดตเตผเดคเตเดคเดฟเด•เตเด•เตเดฎเตเดชเต‹เตพ เดžเด™เตเด™เดณเตเดŸเต† เด…เดญเตเดฏเตผเดคเตเดฅเดจ เดชเตเดฐเด•เดพเดฐเด‚ เดŽเด™เตเด™เดจเต†เดฏเต†เด™เตเด•เดฟเดฒเตเด‚ เด…เดตเดฐเตเดŸเต† DAG เดŸเตเดฐเดฟเด—เตผ เดšเต†เดฏเตเดฏเต‡เดฃเตเดŸเดคเตเดฃเตเดŸเต†เดจเตเดจเต เด‡เดคเต เดฎเดพเดฑเตเดจเตเดจเต. เด—เต‚เด—เตเดฒเดฟเด™เตเด™เดฟเตฝ, เดŽเดฏเตผเดซเตเดฒเต‹เดฏเตเดŸเต† เดชเดฟเดจเตเดจเต€เดŸเตเดณเตเดณ เดชเดคเดฟเดชเตเดชเตเด•เตพเด•เตเด•เต เดตเดฟเดณเดฟเด•เตเด•เดชเตเดชเต†เดŸเตเดจเตเดจ เด’เดจเตเดจเต เด‰เดฃเตเดŸเต†เดจเตเดจเต เดžเด™เตเด™เตพ เด•เดฃเตเดŸเต†เดคเตเดคเดฟ เดชเดฐเต€เด•เตเดทเดฃเดพเดคเตเดฎเด• API. เดตเดพเด•เตเด•เต experimental, เดคเต€เตผเดšเตเดšเดฏเดพเดฏเตเด‚, เด‡เดคเต เดญเดฏเดชเตเดชเต†เดŸเตเดคเตเดคเตเดจเตเดจเดคเดพเดฏเดฟ เดคเต‹เดจเตเดจเตเดจเตเดจเต, เดชเด•เตเดทเต‡ เดŽเดจเตเดคเตเดšเต†เดฏเตเดฏเดฃเด‚ ... เด…เดคเต เดชเต†เดŸเตเดŸเต†เดจเตเดจเต เดŽเดŸเตเด•เตเด•เตเดจเตเดจเต.

เด…เดŸเตเดคเตเดคเดคเดพเดฏเดฟ, เดžเด™เตเด™เตพ เดฎเตเดดเตเดตเตป เดชเดพเดคเดฏเตเด‚ เดตเดฟเดตเดฐเดฟเด•เตเด•เตเด‚: เดŽเดฏเตผเดซเตเดฒเต‹ เด‡เตปเดธเตเดฑเตเดฑเดพเตพ เดšเต†เดฏเตเดฏเตเดจเตเดจเดคเต เดฎเตเดคเตฝ เดชเดฐเต€เด•เตเดทเดฃเดพเดคเตเดฎเด• API เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต เด’เดฐเต DAG เดŸเตเดฐเดฟเด—เตผ เดšเต†เดฏเตเดฏเตเดจเตเดจ เด’เดฐเต POST เด…เดญเตเดฏเตผเดคเตเดฅเดจ เดธเตƒเดทเตเดŸเดฟเด•เตเด•เตเดจเตเดจเดคเต เดตเดฐเต†. เดžเด™เตเด™เตพ เด‰เดฌเตเดฃเตเดŸเต 16.04 เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต เดชเตเดฐเดตเตผเดคเตเดคเดฟเด•เตเด•เตเด‚.

1. เดŽเดฏเตผเดซเตเดฒเต‹ เด‡เตปเดธเตเดฑเตเดฑเดพเดณเต‡เดทเตป

เดจเดฎเตเด•เตเด•เต Python 3 เด‰เด‚ virtualenv เด‰เด‚ เด‰เดฃเตเดŸเต‹ เดŽเดจเตเดจเต เดชเดฐเดฟเดถเต‹เดงเดฟเด•เตเด•เดพเด‚.

$ python3 --version
Python 3.6.6
$ virtualenv --version
15.2.0

เด‡เดตเดฏเดฟเดฒเตŠเดจเตเดจเต เดจเดทเตเดŸเดชเตเดชเต†เดŸเตเดŸเดพเตฝ, เด…เดคเต เด‡เตปเดธเตเดฑเตเดฑเดพเตพ เดšเต†เดฏเตเดฏเตเด•.

เด‡เดชเตเดชเต‹เตพ เดจเดฎเตเด•เตเด•เต เด’เดฐเต เดกเดฏเดฑเด•เตโ€ŒเดŸเดฑเดฟ เดธเตƒเดทเตโ€ŒเดŸเดฟเด•เตเด•เดพเด‚, เด…เดคเดฟเตฝ เดžเด™เตเด™เตพ เดŽเดฏเตผเดซเตเดฒเต‹เดฏเตโ€Œเด•เตเด•เตŠเดชเตเดชเด‚ เดชเตเดฐเดตเตผเดคเตเดคเดฟเด•เตเด•เตเดจเตเดจเดคเต เดคเตเดŸเดฐเตเด‚.

$ mkdir <your name of directory>
$ cd /path/to/your/new/directory
$ virtualenv -p which python3 venv
$ source venv/bin/activate
(venv) $

เดŽเดฏเตผเดซเตเดฒเต‹ เด‡เตปเดธเตเดฑเตเดฑเดพเตพ เดšเต†เดฏเตเดฏเตเด•:

(venv) $ pip install airflow

เดžเด™เตเด™เตพ เดชเตเดฐเดตเตผเดคเตเดคเดฟเดšเตเดš เดชเดคเดฟเดชเตเดชเต: 1.10.

เด‡เดชเตเดชเต‹เตพ เดจเดฎเตเดฎเตพ เด’เดฐเต เดกเดฏเดฑเด•เตเดŸเดฑเดฟ เด‰เดฃเตเดŸเดพเด•เตเด•เดฃเด‚ airflow_home, DAG เดซเดฏเดฒเตเด•เดณเตเด‚ เดŽเดฏเตผเดซเตเดฒเต‹ เดชเตเดฒเด—เดฟเดจเตเดจเตเด•เดณเตเด‚ เดŽเดตเดฟเดŸเต†เดฏเดพเดฃเต เดธเตเดฅเดฟเดคเดฟ เดšเต†เดฏเตเดฏเตเดจเตเดจเดคเต. เดกเดฏเดฑเด•เตเดŸเดฑเดฟ เดธเตƒเดทเตเดŸเดฟเดšเตเดš เดถเต‡เดทเด‚, เดชเดฐเดฟเดธเตเดฅเดฟเดคเดฟ เดตเต‡เดฐเดฟเดฏเดฌเดฟเตพ เดธเดœเตเดœเดฎเดพเด•เตเด•เตเด• AIRFLOW_HOME.

(venv) $ cd /path/to/my/airflow/workspace
(venv) $ mkdir airflow_home
(venv) $ export AIRFLOW_HOME=<path to airflow_home>

SQLite-เตฝ เดกเดพเดฑเตเดฑเดพเดซเตเดฒเต‹ เดกเดพเดฑเตเดฑเดพเดฌเต‡เดธเต เดธเตƒเดทเตเดŸเดฟเด•เตเด•เตเด•เดฏเตเด‚ เดธเดฎเดพเดฐเด‚เดญเดฟเด•เตเด•เตเด•เดฏเตเด‚ เดšเต†เดฏเตเดฏเตเดจเตเดจ เด•เดฎเดพเตปเดกเต เดชเตเดฐเดตเตผเดคเตเดคเดฟเดชเตเดชเดฟเด•เตเด•เตเด• เดŽเดจเตเดจเดคเดพเดฃเต เด…เดŸเตเดคเตเดค เด˜เดŸเตเดŸเด‚:

(venv) $ airflow initdb

เดกเดพเดฑเตเดฑเดพเดฌเต‡เดธเต เดธเตƒเดทเตเดŸเดฟเด•เตเด•เดชเตเดชเต†เดŸเตเด‚ airflow.db เดธเตเดฅเดฟเดฐเดธเตเดฅเดฟเดคเดฟ.

เดŽเดฏเตผเดซเตเดฒเต‹ เด‡เตปเดธเตเดฑเตเดฑเดพเตพ เดšเต†เดฏเตเดคเดฟเดŸเตเดŸเตเดฃเตเดŸเต‹เดฏเต†เดจเตเดจเต เดชเดฐเดฟเดถเต‹เดงเดฟเด•เตเด•เดพเด‚:

$ airflow version
[2018-11-26 19:38:19,607] {__init__.py:57} INFO - Using executor SequentialExecutor
[2018-11-26 19:38:19,745] {driver.py:123} INFO - Generating grammar tables from /usr/lib/python3.6/lib2to3/Grammar.txt
[2018-11-26 19:38:19,771] {driver.py:123} INFO - Generating grammar tables from /usr/lib/python3.6/lib2to3/PatternGrammar.txt
  ____________       _____________
 ____    |__( )_________  __/__  /________      __
____  /| |_  /__  ___/_  /_ __  /_  __ _ | /| / /
___  ___ |  / _  /   _  __/ _  / / /_/ /_ |/ |/ /
 _/_/  |_/_/  /_/    /_/    /_/  ____/____/|__/
   v1.10.0

เด•เดฎเดพเตปเดกเต เดชเตเดฐเดตเตผเดคเตเดคเดฟเด•เตเด•เตเดจเตเดจเตเดฃเตเดŸเต†เด™เตเด•เดฟเตฝ, เดŽเดฏเตผเดซเตเดฒเต‹ เด…เดคเดฟเดจเตเดฑเต‡เดคเดพเดฏ เด•เต‹เตบเดซเดฟเด—เดฑเต‡เดทเตป เดซเดฏเตฝ เดธเตƒเดทเตเดŸเดฟเดšเตเดšเต airflow.cfg ะฒ AIRFLOW_HOME:

$ tree
.
โ”œโ”€โ”€ airflow.cfg
โ””โ”€โ”€ unittests.cfg

เดŽเดฏเตผเดซเตเดฒเต‹เดฏเตเด•เตเด•เต เด’เดฐเต เดตเต†เดฌเต เด‡เดจเตเดฑเตผเดซเต‡เดธเต เด‰เดฃเตเดŸเต. เด•เดฎเดพเตปเดกเต เดชเตเดฐเดตเตผเดคเตเดคเดฟเดชเตเดชเดฟเดšเตเดšเต เด‡เดคเต เดธเดฎเดพเดฐเด‚เดญเดฟเด•เตเด•เดพเด‚:

(venv) $ airflow webserver --port 8081

เดŽเดฏเตผเดซเตเดฒเต‹ เดชเตเดฐเดตเตผเดคเตเดคเดฟเด•เตเด•เตเดจเตเดจ เดนเต‹เดธเตเดฑเตเดฑเดฟเดฒเต† เดชเต‹เตผเดŸเตเดŸเต 8081-เดฒเต† เดฌเตเดฐเต—เดธเดฑเดฟเตฝ เดจเดฟเด™เตเด™เตพเด•เตเด•เต เด‡เดชเตเดชเต‹เตพ เดตเต†เดฌเต เด‡เดจเตเดฑเตผเดซเต‡เดธเต เด†เด•เตโ€Œเดธเดธเต เดšเต†เดฏเตเดฏเดพเตป เด•เดดเดฟเดฏเตเด‚: <hostname:8081>.

2. เดชเดฐเต€เด•เตเดทเดฃเดพเดคเตเดฎเด• API เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต เดชเตเดฐเดตเตผเดคเตเดคเดฟเด•เตเด•เตเดจเตเดจเต

เด‡เดคเดฟเตฝ เดŽเดฏเตผเดซเตเดฒเต‹ เด•เต‹เตบเดซเดฟเด—เตผ เดšเต†เดฏเตโ€Œเดคเต เดชเต‹เด•เดพเตป เดคเดฏเตเดฏเดพเดฑเดพเดฃเต. เดŽเดจเตเดจเดฟเดฐเตเดจเตเดจเดพเดฒเตเด‚, เดžเด™เตเด™เตพ เดชเดฐเต€เด•เตเดทเดฃเดพเดคเตเดฎเด• API เดชเตเดฐเดตเตผเดคเตเดคเดฟเดชเตเดชเดฟเด•เตเด•เต‡เดฃเตเดŸเดคเตเดฃเตเดŸเต. เดžเด™เตเด™เดณเตเดŸเต† เดšเต†เด•เตเด•เดฑเตเด•เตพ เดชเตˆเดคเตเดคเดฃเดฟเดฒเดพเดฃเต เดŽเดดเตเดคเดฟเดฏเดฟเดฐเดฟเด•เตเด•เตเดจเตเดจเดคเต, เด…เดคเดฟเดจเดพเตฝ เดฒเตˆเดฌเตเดฐเดฑเดฟ เด‰เดชเดฏเต‹เด—เดฟเดšเตเดšเต เด•เต‚เดŸเตเดคเตฝ เด…เดญเตเดฏเตผเดคเตเดฅเดจเด•เตพ เด…เดคเดฟเตฝ เด‰เดฃเตเดŸเดพเด•เตเด‚ requests.

เดฏเดฅเดพเตผเดคเตเดฅเดคเตเดคเดฟเตฝ API เด‡เดคเดฟเดจเด•เด‚ เดคเดจเตเดจเต† เดฒเดณเดฟเดคเดฎเดพเดฏ เด…เดญเตเดฏเตผเดคเตเดฅเดจเด•เตพเด•เตเด•เดพเดฏเดฟ เดชเตเดฐเดตเตผเดคเตเดคเดฟเด•เตเด•เตเดจเตเดจเต. เด‰เดฆเดพเดนเดฐเดฃเดคเตเดคเดฟเดจเต, เด…เดคเตเดคเดฐเดฎเตŠเดฐเต เด…เดญเตเดฏเตผเดคเตเดฅเดจ เด…เดคเดฟเดจเตเดฑเต† เดœเต‹เดฒเดฟ เดชเดฐเดฟเดถเต‹เดงเดฟเด•เตเด•เดพเตป เดจเดฟเด™เตเด™เดณเต† เด…เดจเตเดตเดฆเดฟเด•เตเด•เตเดจเตเดจเต:

>>> import requests
>>> host = <your hostname>
>>> airflow_port = 8081 #ะฒ ะฝะฐัˆะตะผ ัะปัƒั‡ะฐะต ั‚ะฐะบะพะน, ะฐ ะฟะพ ะดะตั„ะพะปั‚ัƒ 8080
>>> requests.get('http://{}:{}/{}'.format(host, airflow_port, 'api/experimental/test').text
'OK'

เดชเตเดฐเดคเดฟเด•เดฐเดฃเดฎเดพเดฏเดฟ เดจเดฟเด™เตเด™เตพเด•เตเด•เต เด…เดคเตเดคเดฐเดฎเตŠเดฐเต เดธเดจเตเดฆเต‡เดถเด‚ เดฒเดญเดฟเดšเตเดšเดพเตฝ, เดŽเดฒเตเดฒเดพเด‚ เดชเตเดฐเดตเตผเดคเตเดคเดฟเด•เตเด•เตเดจเตเดจเต เดŽเดจเตเดจเดพเดฃเต เด‡เดคเดฟเดจเตผเดคเตเดฅเด‚.

เดŽเดจเตเดจเดฟเดฐเตเดจเตเดจเดพเดฒเตเด‚, DAG เดชเตเดฐเดตเตผเดคเตเดคเดจเด•เตเดทเดฎเดฎเดพเด•เตเด•เดพเตป เดžเด™เตเด™เตพ เด†เด—เตเดฐเดนเดฟเด•เตเด•เตเดฎเตเดชเต‹เตพ, เด†เดงเดฟเด•เดพเดฐเดฟเด•เดค เด‰เดฑเดชเตเดชเดพเด•เตเด•เดพเดคเต† เด‡เดคเตเดคเดฐเดคเตเดคเดฟเดฒเตเดณเตเดณ เด…เดญเตเดฏเตผเดคเตเดฅเดจ เดจเดŸเดคเตเดคเดพเตป เด•เดดเดฟเดฏเดฟเดฒเตเดฒ เดŽเดจเตเดจ เดตเดธเตเดคเตเดคเดฏเดฟเดฒเต‡เด•เตเด•เต เดžเด™เตเด™เตพ เด•เดŸเดจเตเดจเตเดชเต‹เด•เตเดจเตเดจเต.

เด‡เดคเต เดšเต†เดฏเตเดฏเตเดจเตเดจเดคเดฟเดจเต, เดจเดฟเด™เตเด™เตพ เด•เต‚เดŸเตเดคเตฝ เด˜เดŸเตเดŸเด™เตเด™เตพ เดšเต†เดฏเตเดฏเต‡เดฃเตเดŸเดคเตเดฃเตเดŸเต.

เด†เดฆเตเดฏเด‚, เดจเดฟเด™เตเด™เตพ เด‡เดคเต เด•เต‹เตบเดซเดฟเด—เดฑเดฟเดฒเต‡เด•เตเด•เต เดšเต‡เตผเด•เตเด•เต‡เดฃเตเดŸเดคเตเดฃเตเดŸเต:

[api]
auth_backend = airflow.contrib.auth.backends.password_auth

เดคเตเดŸเตผเดจเตเดจเต, เด…เดกเตเดฎเดฟเตป เด…เดตเด•เดพเดถเด™เตเด™เดณเต‹เดŸเต† เดจเดฟเด™เตเด™เดณเตเดŸเต† เด‰เดชเดฏเต‹เด•เตเดคเดพเดตเดฟเดจเต† เดธเตƒเดทเตเดŸเดฟเด•เตเด•เต‡เดฃเตเดŸเดคเตเดฃเตเดŸเต:

>>> import airflow
>>> from airflow import models, settings
>>> from airflow.contrib.auth.backends.password_auth import PasswordUser
>>> user = PasswordUser(models.Admin())
>>> user.username = 'new_user_name'
>>> user.password = 'set_the_password'
>>> session = settings.Session()
>>> session.add(user)
>>> session.commit()
>>> session.close()
>>> exit()

เด…เดŸเตเดคเตเดคเดคเดพเดฏเดฟ, เด’เดฐเต DAG เดŸเตเดฐเดฟเด—เตผ เดจเดฟเตผเดฎเตเดฎเดฟเด•เตเด•เดพเตป เด…เดจเตเดตเดฆเดฟเด•เตเด•เตเดจเตเดจ เดธเดพเดงเดพเดฐเดฃ เด…เดตเด•เดพเดถเด™เตเด™เดณเตเดณเตเดณ เด’เดฐเต เด‰เดชเดฏเต‹เด•เตเดคเดพเดตเดฟเดจเต† เดจเดฟเด™เตเด™เตพ เดธเตƒเดทเตเดŸเดฟเด•เตเด•เต‡เดฃเตเดŸเดคเตเดฃเตเดŸเต.

>>> import airflow
>>> from airflow import models, settings
>>> from airflow.contrib.auth.backends.password_auth import PasswordUser
>>> user = PasswordUser(models.User())
>>> user.username = 'newprolab'
>>> user.password = 'Newprolab2019!'
>>> session = settings.Session()
>>> session.add(user)
>>> session.commit()
>>> session.close()
>>> exit()

เด‡เดชเตเดชเต‹เตพ เดŽเดฒเตเดฒเดพเด‚ เดคเดฏเตเดฏเดพเดฑเดพเดฃเต.

3. เด’เดฐเต POST เด…เดญเตเดฏเตผเดคเตเดฅเดจ เดธเดฎเดพเดฐเด‚เดญเดฟเด•เตเด•เตเดจเตเดจเต

POST เด…เดญเตเดฏเตผเดคเตเดฅเดจ เดคเดจเตเดจเต† เด‡เดคเตเดชเต‹เดฒเต† เด•เดพเดฃเดชเตเดชเต†เดŸเตเด‚:

>>> dag_id = newprolab
>>> url = 'http://{}:{}/{}/{}/{}'.format(host, airflow_port, 'api/experimental/dags', dag_id, 'dag_runs')
>>> data = {"conf":"{"key":"value"}"}
>>> headers = {'Content-type': 'application/json'}
>>> auth = ('newprolab', 'Newprolab2019!')
>>> uri = requests.post(url, data=json.dumps(data), headers=headers, auth=auth)
>>> uri.text
'{n  "message": "Created <DagRun newprolab @ 2019-03-27 10:24:25+00:00: manual__2019-03-27T10:24:25+00:00, externally triggered: True>"n}n'

เด…เดญเตเดฏเตผเดคเตเดฅเดจ เดตเดฟเดœเดฏเด•เดฐเดฎเดพเดฏเดฟ เดชเตเดฐเต‹เดธเดธเตเดธเต เดšเต†เดฏเตเดคเต.

เด…เดคเดจเตเดธเดฐเดฟเดšเตเดšเต, เดจเดฟเดฏเดจเตเดคเตเดฐเดฃ เดกเดพเดฑเตเดฑ เดชเดพเด•เตเด•เดฑเตเดฑเต เดชเดฟเดŸเดฟเด•เตเด•เดพเตป เดถเตเดฐเดฎเดฟเด•เตเด•เตเดจเตเดจ เด•เตเดฒเดฟเด•เตเด•เตเดนเต—เดธเต เดŸเต‡เดฌเดฟเดณเดฟเดฒเต‡เด•เตเด•เต เดชเตเดฐเต‹เดธเดธเตเดธเต เดšเต†เดฏเตเดฏเดพเดจเตเด‚ เด’เดฐเต เด…เดญเตเดฏเตผเดคเตเดฅเดจ เดจเดŸเดคเตเดคเดพเดจเตเด‚ เดžเด™เตเด™เตพ DAG-เด•เตเด•เต เด•เตเดฑเดšเตเดšเต เดธเดฎเดฏเด‚ เดจเตฝเด•เตเดจเตเดจเต.

เดชเดฐเดฟเดถเต‹เดงเดจ เดชเต‚เตผเดคเตเดคเดฟเดฏเดพเดฏเดฟ.

เด…เดตเดฒเด‚เดฌเด‚: www.habr.com

เด’เดฐเต เด…เดญเดฟเดชเตเดฐเดพเดฏเด‚ เดšเต‡เตผเด•เตเด•เตเด•