เชชเซเชฐเชพเชฏเซ‹เช—เชฟเช• API เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡ เชเชฐเชซเซเชฒเซ‹เชฎเชพเช‚ DAG เชŸเซเชฐเชฟเช—เชฐ เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เชฌเชจเชพเชตเชตเซเช‚

เช…เชฎเชพเชฐเชพ เชถเซˆเช•เซเชทเชฃเชฟเช• เช•เชพเชฐเซเชฏเช•เซเชฐเชฎเซ‹ เชคเซˆเชฏเชพเชฐ เช•เชฐเชคเซ€ เชตเช–เชคเซ‡, เช…เชฎเซ‡ เชธเชฎเชฏเชพเช‚เชคเชฐเซ‡ เช…เชฎเซเช• เชธเชพเชงเชจเซ‹ เชธเชพเชฅเซ‡ เช•เชพเชฎ เช•เชฐเชตเชพเชฎเชพเช‚ เชฎเซเชถเซเช•เซ‡เชฒเซ€เช“เชจเซ‹ เชธเชพเชฎเชจเซ‹ เช•เชฐเซ€เช เช›เซ€เช. เช…เชจเซ‡ เช† เช•เซเชทเชฃเซ‡ เชœเซเชฏเชพเชฐเซ‡ เช†เชชเชฃเซ‡ เชคเซ‡เชฎเชจเซ‹ เชธเชพเชฎเชจเซ‹ เช•เชฐเซ€เช เช›เซ€เช, เชคเซเชฏเชพเช‚ เชนเช‚เชฎเซ‡เชถเชพ เชชเซ‚เชฐเชคเชพ เชฆเชธเซเชคเชพเชตเซ‡เชœเซ‹ เช…เชจเซ‡ เชฒเซ‡เช–เซ‹ เชจเชฅเซ€ เช•เซ‡ เชœเซ‡ เช…เชฎเชจเซ‡ เช† เชธเชฎเชธเซเชฏเชพเชจเซ‹ เชธเชพเชฎเชจเซ‹ เช•เชฐเชตเชพเชฎเชพเช‚ เชฎเชฆเชฆ เช•เชฐเซ‡.

เช† เช•เซ‡เชธ เชนเชคเซ‹, เช‰เชฆเชพเชนเชฐเชฃ เชคเชฐเซ€เช•เซ‡, 2015 เชฎเชพเช‚, เช…เชจเซ‡ โ€œเชฌเชฟเช— เชกเซ‡เชŸเชพ เชธเซเชชเซ‡เชถเชฟเชฏเชพเชฒเชฟเชธเซเชŸโ€ เชชเซเชฐเซ‹เช—เซเชฐเชพเชฎ เชฆเชฐเชฎเชฟเชฏเชพเชจ เช…เชฎเซ‡ เชเช• เชธเชพเชฅเซ‡ 35 เชตเชชเชฐเชพเชถเช•เชฐเซเชคเชพเช“ เชฎเชพเชŸเซ‡ เชธเซเชชเชพเชฐเซเช• เชธเชพเชฅเซ‡เชจเชพ เชนเชกเซเชช เช•เซเชฒเชธเซเชŸเชฐเชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซเชฏเซ‹ เชนเชคเซ‹. เชฏเชพเชฐเซเชจเชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡ เช†เชตเชพ เช‰เชชเชฏเซ‹เช— เช•เซ‡เชธ เชฎเชพเชŸเซ‡ เชคเซ‡เชจเซ‡ เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เชคเซˆเชฏเชพเชฐ เช•เชฐเชตเซเช‚ เชคเซ‡ เชธเซเชชเชทเซเชŸ เชจ เชนเชคเซเช‚. เช…เช‚เชคเซ‡, เชคเซ‡ เชถเซ‹เชงเซ€ เช•เชพเชขเซเชฏเชพ เช…เชจเซ‡ เช…เชฎเชพเชฐเซ€ เชœเชพเชคเซ‡ เชœ เชฎเชพเชฐเซเช— เชชเชฐ เชšเชพเชฒเซเชฏเชพ, เช…เชฎเซ‡ เช•เชฐเซเชฏเซเช‚ Habrรฉ เชชเชฐ เชชเซ‹เชธเซเชŸ เช…เชจเซ‡ เช–เชพเชคเซ‡ เชชเชฃ เชชเซเชฐเชฆเชฐเซเชถเชจ เช•เชฐเซเชฏเซเช‚ เชนเชคเซเช‚ เชฎเซ‹เชธเซเช•เซ‹ เชธเซเชชเชพเชฐเซเช• เชฎเซ€เชŸเช…เชช.

เชชเซเชฐเชพเช—เซˆเชคเชฟเชนเชพเชธเชฟเช•

เช† เชตเช–เชคเซ‡ เช†เชชเชฃเซ‡ เชเช• เช…เชฒเช— เชชเซเชฐเซ‹เช—เซเชฐเชพเชฎ เชตเชฟเชถเซ‡ เชตเชพเชค เช•เชฐเซ€เชถเซเช‚ - เชกเซ‡เชŸเชพ เช‡เชœเชจเซ‡เชฐ. เช…เชฎเชพเชฐเชพ เชธเชนเชญเชพเช—เซ€เช“ เชคเซ‡เชจเชพ เชชเชฐ เชฌเซ‡ เชชเซเชฐเช•เชพเชฐเชจเชพ เช†เชฐเซเช•เชฟเชŸเซ‡เช•เซเชšเชฐ เชฌเชจเชพเชตเซ‡ เช›เซ‡: เชฒเซ‡เชฎเซเชฌเชกเชพ เช…เชจเซ‡ เช•เชชเซเชชเชพ. เช…เชจเซ‡ lamdba เช†เชฐเซเช•เชฟเชŸเซ‡เช•เซเชšเชฐเชฎเชพเช‚, เชฌเซ‡เชš เชชเซเชฐเซ‹เชธเซ‡เชธเชฟเช‚เช—เชจเชพ เชญเชพเช— เชฐเซ‚เชชเซ‡, เชเชฐเชซเซเชฒเซ‹เชจเซ‹ เช‰เชชเชฏเซ‹เช— HDFS เชฅเซ€ เช•เซเชฒเชฟเช•เชนเชพเช‰เชธเชฎเชพเช‚ เชฒเซ‹เช— เชŸเซเชฐเชพเชจเซเชธเชซเชฐ เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เชฅเชพเชฏ เช›เซ‡.

เชฌเชงเซเช‚ เชธเชพเชฎเชพเชจเซเชฏ เชฐเซ€เชคเซ‡ เชธเชพเชฐเซเช‚ เช›เซ‡. เชคเซ‡เชฎเชจเซ‡ เชชเซ‹เชคเชพเชจเซ€ เชชเชพเช‡เชชเชฒเชพเช‡เชจ เชฌเชจเชพเชตเชตเชพ เชฆเซ‹. เชœเซ‹ เช•เซ‡, เชคเซเชฏเชพเช‚ เชเช• "เชชเชฐเช‚เชคเซ" เช›เซ‡: เช…เชฎเชพเชฐเชพ เชฌเชงเชพ เชชเซเชฐเซ‹เช—เซเชฐเชพเชฎเซเชธ เชถเซ€เช–เชตเชพเชจเซ€ เชชเซเชฐเช•เซเชฐเชฟเชฏเชพเชจเชพ เชฆเซƒเชทเซเชŸเชฟเช•เซ‹เชฃเชฅเซ€ เชคเช•เชจเซ€เช•เซ€ เชฐเซ€เชคเซ‡ เช…เชฆเซเชฏเชคเชจ เช›เซ‡. เชฒเซ‡เชฌ เชคเชชเชพเชธเชตเชพ เชฎเชพเชŸเซ‡, เช…เชฎเซ‡ เชธเซเชตเชšเชพเชฒเชฟเชค เชšเซ‡เช•เชฐเซเชธเชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เช เช›เซ€เช: เชธเชนเชญเชพเช—เซ€เชจเซ‡ เชคเซ‡เชจเชพ เชตเซเชฏเช•เซเชคเชฟเช—เชค เช–เชพเชคเชพเชฎเชพเช‚ เชœเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เช›เซ‡, "เชšเซ‡เช•" เชฌเชŸเชจเชจเซ‡ เช•เซเชฒเชฟเช• เช•เชฐเซ‹, เช…เชจเซ‡ เชฅเซ‹เชกเชพ เชธเชฎเชฏ เชชเช›เซ€ เชคเซ‡เชฃเซ‡ เชœเซ‡ เช•เชฐเซเชฏเซเช‚ เชคเซ‡เชจเชพ เชชเชฐ เช•เซ‹เชˆ เชชเซเชฐเช•เชพเชฐเชจเซ‹ เชตเชฟเชธเซเชคเซƒเชค เชชเซเชฐเชคเชฟเชธเชพเชฆ เชœเซเช เช›เซ‡. เช…เชจเซ‡ เชคเซ‡ เช† เช•เซเชทเชฃเซ‡ เช›เซ‡ เช•เซ‡ เช†เชชเชฃเซ‡ เช†เชชเชฃเซ€ เชธเชฎเชธเซเชฏเชพเชจเซ‹ เชธเช‚เชชเชฐเซเช• เช•เชฐเชตเชพเชจเซเช‚ เชถเชฐเซ‚ เช•เชฐเซ€เช เช›เซ€เช.

เช† เชฒเซ‡เชฌเชจเซ€ เชšเช•เชพเชธเชฃเซ€ เช† เชฐเซ€เชคเซ‡ เชฐเชšเชพเชฏเซ‡เชฒ เช›เซ‡: เช…เชฎเซ‡ เชธเชนเชญเชพเช—เซ€เชจเชพ เช•เชพเชซเซเช•เชพเชจเซ‡ เช•เช‚เชŸเซเชฐเซ‹เชฒ เชกเซ‡เชŸเชพ เชชเซ‡เช•เซ‡เชŸ เชฎเซ‹เช•เชฒเซ€เช เช›เซ€เช, เชชเช›เซ€ เช—เซ‹เชฌเซเชฒเชฟเชจ เช† เชกเซ‡เชŸเชพ เชชเซ‡เช•เซ‡เชŸเชจเซ‡ HDFS เชชเชฐ เชŸเซเชฐเชพเชจเซเชธเชซเชฐ เช•เชฐเซ‡ เช›เซ‡, เชชเช›เซ€ เชเชฐเชซเซเชฒเซ‹ เช† เชกเซ‡เชŸเชพ เชชเซ‡เช•เซ‡เชŸ เชฒเซ‡ เช›เซ‡ เช…เชจเซ‡ เชคเซ‡เชจเซ‡ เช•เซเชฒเชฟเช•เชนเชพเช‰เชธเชฎเชพเช‚ เชฎเซ‚เช•เซ‡ เช›เซ‡. เชฏเซเช•เซเชคเชฟ เช เช›เซ‡ เช•เซ‡ เชเชฐเชซเซเชฒเซ‹เชจเซ‡ เชตเชพเชธเซเชคเชตเชฟเช• เชธเชฎเชฏเชฎเชพเช‚ เช† เช•เชฐเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เชจเชฅเซ€, เชคเซ‡ เชถเซ‡เชกเซเชฏเซ‚เชฒ เช…เชจเซเชธเชพเชฐ เช•เชฐเซ‡ เช›เซ‡: เชฆเชฐ 15 เชฎเชฟเชจเชฟเชŸเซ‡ เชคเซ‡ เชซเชพเช‡เชฒเซ‹เชจเซ‹ เชธเชฎเซ‚เชน เชฒเซ‡ เช›เซ‡ เช…เชจเซ‡ เชคเซ‡เชจเซ‡ เช…เชชเชฒเซ‹เชก เช•เชฐเซ‡ เช›เซ‡.

เชคเซ‡ เชคเชพเชฐเชฃ เช†เชชเซ‡ เช›เซ‡ เช•เซ‡ เช…เชฎเชพเชฐเซ‡ เช…เชฎเชพเชฐเซ€ เชตเชฟเชจเช‚เชคเซ€ เชชเชฐ เช•เซ‹เชˆเช• เชฐเซ€เชคเซ‡ เชคเซ‡เชฎเชจเชพ DAG เชจเซ‡ เชŸเซเชฐเชฟเช—เชฐ เช•เชฐเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เช›เซ‡ เชœเซเชฏเชพเชฐเซ‡ เชšเซ‡เช•เชฐ เช…เชนเซ€เช‚ เช…เชจเซ‡ เช…เชคเซเชฏเชพเชฐเซ‡ เชšเชพเชฒเซ€ เชฐเชนเซเชฏเซเช‚ เช›เซ‡. เช—เซ‚เช—เชฒเชฟเช‚เช— เช•เชฐเซเชฏเชพ เชชเช›เซ€, เช…เชฎเชจเซ‡ เชœเชพเชฃเชตเชพ เชฎเชณเซเชฏเซเช‚ เช•เซ‡ เชเชฐเชซเซเชฒเซ‹เชจเชพ เชชเช›เซ€เชจเชพ เชธเช‚เชธเซเช•เชฐเชฃเซ‹ เชฎเชพเชŸเซ‡ เช•เชนเซ‡เชตเชพเชคเชพ เช›เซ‡ เชชเซเชฐเชพเชฏเซ‹เช—เชฟเช• API. เชถเชฌเซเชฆ experimental, เช…เชฒเชฌเชคเซเชค, เชคเซ‡ เชกเชฐเชพเชฎเชฃเซ€ เชฒเชพเช—เซ‡ เช›เซ‡, เชชเชฐเช‚เชคเซ เชถเซเช‚ เช•เชฐเชตเซเช‚... เช…เชšเชพเชจเช• เชคเซ‡ เชฌเช‚เชง เชฅเชˆ เชœเชพเชฏ เช›เซ‡.

เช†เช—เชณ, เช…เชฎเซ‡ เชธเชฎเช—เซเชฐ เชชเชพเชฅเชจเซเช‚ เชตเชฐเซเชฃเชจ เช•เชฐเซ€เชถเซเช‚: เชเชฐเชซเซเชฒเซ‹ เช‡เชจเซเชธเซเชŸเซ‹เชฒ เช•เชฐเชตเชพเชฅเซ€ เชฒเชˆเชจเซ‡ POST เชตเชฟเชจเช‚เชคเซ€ เชœเชจเชฐเซ‡เชŸ เช•เชฐเชตเชพ เชธเซเชงเซ€ เชœเซ‡ เชชเซเชฐเชพเชฏเซ‹เช—เชฟเช• API เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡ DAG เชจเซ‡ เชŸเซเชฐเชฟเช—เชฐ เช•เชฐเซ‡ เช›เซ‡. เช…เชฎเซ‡ เช‰เชฌเซเชจเซเชŸเซ 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

เชเช• เชŸเชฟเชชเซเชชเชฃเซ€ เช‰เชฎเซ‡เชฐเซ‹