เจชเฉเจฐเจฏเฉ‹เจ—เจพเจคเจฎเจ• API เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจ•เฉ‡ เจเจ…เจฐเจซเจฒเฉ‹ เจตเจฟเฉฑเจš เจ‡เฉฑเจ• DAG เจŸเจฐเจฟเฉฑเจ—เจฐ เจ•เจฟเจตเฉ‡เจ‚ เจฌเจฃเจพเจ‡เจ† เจœเจพเจตเฉ‡

เจธเจพเจกเฉ‡ เจตเจฟเจฆเจฟเจ…เจ• เจชเฉเจฐเฉ‹เจ—เจฐเจพเจฎเจพเจ‚ เจจเฉ‚เฉฐ เจคเจฟเจ†เจฐ เจ•เจฐเจฆเฉ‡ เจธเจฎเฉ‡เจ‚, เจธเจพเจจเฉ‚เฉฐ เจธเจฎเฉ‡เจ‚-เจธเจฎเฉ‡เจ‚ 'เจคเฉ‡ เจ•เฉเจ เจธเจพเจงเจจเจพเจ‚ เจจเจพเจฒ เจ•เฉฐเจฎ เจ•เจฐเจจ เจฆเฉ‡ เจฎเจพเจฎเจฒเฉ‡ เจตเจฟเฉฑเจš เจฎเฉเจธเจผเจ•เจฒเจพเจ‚ เจฆเจพ เจธเจพเจนเจฎเจฃเจพ เจ•เจฐเจจเจพ เจชเฉˆเจ‚เจฆเจพ เจนเฉˆเฅค เจ…เจคเฉ‡ เจ‡เจธ เจธเจฎเฉ‡เจ‚ เจœเจฆเฉ‹เจ‚ เจ…เจธเฉ€เจ‚ เจ‰เจนเจจเจพเจ‚ เจฆเจพ เจธเจพเจนเจฎเจฃเจพ เจ•เจฐเจฆเฉ‡ เจนเจพเจ‚, เจ‡เฉฑเจฅเฉ‡ เจนเจฎเฉ‡เจธเจผเจพ เจฒเฉ‹เฉœเฉ€เจ‚เจฆเฉ‡ เจฆเจธเจคเจพเจตเฉ‡เจœเจผ เจ…เจคเฉ‡ เจฒเฉ‡เจ– เจจเจนเฉ€เจ‚ เจนเฉเฉฐเจฆเฉ‡ เจนเจจ เจœเฉ‹ เจ‡เจธ เจธเจฎเฉฑเจธเจฟเจ† เจจเจพเจฒ เจธเจฟเฉฑเจเจฃ เจตเจฟเฉฑเจš เจธเจพเจกเฉ€ เจฎเจฆเจฆ เจ•เจฐเจจเจ—เฉ‡เฅค

เจ‡เจน เจฎเจพเจฎเจฒเจพ เจธเฉ€, เจ‰เจฆเจพเจนเจฐเจจ เจฒเจˆ, 2015 เจตเจฟเฉฑเจš, เจ…เจคเฉ‡ "เจฌเจฟเจ— เจกเฉ‡เจŸเจพ เจธเจชเฉˆเจธเจผเจฒเจฟเจธเจŸ" เจชเฉเจฐเฉ‹เจ—เจฐเจพเจฎ เจฆเฉ‡ เจฆเฉŒเจฐเจพเจจ เจ…เจธเฉ€เจ‚ 35 เจ‡เฉฑเจ•เฉ‹ เจธเจฎเฉ‡เจ‚ เจฆเฉ‡ เจ‰เจชเจญเฉ‹เจ—เจคเจพเจตเจพเจ‚ เจฒเจˆ เจธเจชเจพเจฐเจ• เจฆเฉ‡ เจจเจพเจฒ เจ‡เฉฑเจ• เจนเฉˆเจกเฉ‚เจช เจ•เจฒเฉฑเจธเจŸเจฐ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เฉ€เจคเฉ€เฅค เจ‡เจน เจธเจชเฉฑเจธเจผเจŸ เจจเจนเฉ€เจ‚ เจธเฉ€ เจ•เจฟ เจฏเจพเจฐเจจ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจ•เฉ‡ เจ‡เจธ เจจเฉ‚เฉฐ เจ…เจœเจฟเจนเฉ‡ เจตเจฐเจคเฉ‹เจ‚ เจฆเฉ‡ เจ•เฉ‡เจธ เจฒเจˆ เจ•เจฟเจตเฉ‡เจ‚ เจคเจฟเจ†เจฐ เจ•เจฐเจจเจพ เจนเฉˆเฅค เจ…เฉฐเจค เจตเจฟเฉฑเจš, เจ‡เจธเจฆเจพ เจชเจคเจพ เจฒเจ—เจพ เจ•เฉ‡ เจ…เจคเฉ‡ เจ†เจชเจฃเฉ‡ เจ†เจช เจนเฉ€ เจฐเจธเจคเฉ‡ เจคเฉ‡ เจšเฉฑเจฒเจฆเฉ‡ เจนเฉ‹เจ, เจ…เจธเฉ€เจ‚ เจ•เฉ€เจคเจพ Habrรฉ 'เจคเฉ‡ เจชเฉ‹เจธเจŸ เจ…เจคเฉ‡ เจตเจฟเจ–เฉ‡ เจตเฉ€ เจชเฉเจฐเจฆเจฐเจธเจผเจจ เจ•เฉ€เจคเจพ เจฎเจพเจธเจ•เฉ‹ เจธเจชเจพเจฐเจ• เจฎเฉ€เจŸเจฟเฉฐเจ—.

prehistory

เจ‡เจธ เจตเจพเจฐ เจ…เจธเฉ€เจ‚ เจ‡เฉฑเจ• เจตเฉฑเจ–เจฐเฉ‡ เจชเฉเจฐเฉ‹เจ—เจฐเจพเจฎ เจฌเจพเจฐเฉ‡ เจ—เฉฑเจฒ เจ•เจฐเจพเจ‚เจ—เฉ‡- เจกเจพเจŸเจพ เจ‡เฉฐเจœเฉ€เจจเฉ€เจ…เจฐ. เจธเจพเจกเฉ‡ เจญเจพเจ—เฉ€เจฆเจพเจฐ เจ‡เจธ 'เจคเฉ‡ เจฆเฉ‹ เจ•เจฟเจธเจฎ เจฆเฉ‡ เจ†เจฐเจ•เฉ€เจŸเฉˆเจ•เจšเจฐ เจฌเจฃเจพเจ‰เจ‚เจฆเฉ‡ เจนเจจ: เจฒเจพเจ‚เจฌเจกเจพ เจ…เจคเฉ‡ เจ•เจชเจพเฅค เจ…เจคเฉ‡ lamdba เจ†เจฐเจ•เฉ€เจŸเฉˆเจ•เจšเจฐ เจตเจฟเฉฑเจš, เจฌเฉˆเจš เจชเฉเจฐเฉ‹เจธเฉˆเจธเจฟเฉฐเจ— เจฆเฉ‡ เจนเจฟเฉฑเจธเฉ‡ เจตเจœเฉ‹เจ‚, เจเจ…เจฐเจซเจฒเฉ‹ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจเจšเจกเฉ€เจเจซเจเจธ เจคเฉ‹เจ‚ เจ•เจฒเจฟเจ•เจนเจพเจŠเจธ เจตเจฟเฉฑเจš เจฒเจพเจ—เจพเจ‚ เจจเฉ‚เฉฐ เจŸเฉเจฐเจพเจ‚เจธเจซเจฐ เจ•เจฐเจจ เจฒเจˆ เจ•เฉ€เจคเฉ€ เจœเจพเจ‚เจฆเฉ€ เจนเฉˆเฅค

เจธเจญ เจ•เฉเจ เจ†เจฎ เจคเฉŒเจฐ 'เจคเฉ‡ เจšเฉฐเจ—เจพ เจนเฉˆ. เจ‰เจจเฉเจนเจพเจ‚ เจจเฉ‚เฉฐ เจ†เจชเจฃเฉ€เจ†เจ‚ เจชเจพเจˆเจชเจฒเจพเจˆเจจเจพเจ‚ เจฌเจฃเจพเจ‰เจฃ เจฆเจฟเจ“เฅค เจนเจพเจฒเจพเจ‚เจ•เจฟ, เจ‡เฉฑเจฅเฉ‡ เจ‡เฉฑเจ• "เจชเจฐ" เจนเฉˆ: เจธเจพเจกเฉ‡ เจธเจพเจฐเฉ‡ เจชเฉเจฐเฉ‹เจ—เจฐเจพเจฎ เจธเจฟเฉฑเจ–เจฃ เจฆเฉ€ เจชเฉเจฐเจ•เจฟเจฐเจฟเจ† เจฆเฉ‡ เจฆเฉเจฐเจฟเจธเจผเจŸเฉ€เจ•เฉ‹เจฃ เจคเฉ‹เจ‚ เจคเจ•เจจเฉ€เจ•เฉ€ เจคเฉŒเจฐ 'เจคเฉ‡ เจ‰เฉฑเจจเจค เจนเจจเฅค เจชเฉเจฐเจฏเฉ‹เจ—เจธเจผเจพเจฒเจพ เจฆเฉ€ เจœเจพเจ‚เจš เจ•เจฐเจจ เจฒเจˆ, เจ…เจธเฉ€เจ‚ เจ†เจŸเฉ‹เจฎเฉˆเจŸเจฟเจ• เจšเฉˆเจ•เจฐเจพเจ‚ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจฆเฉ‡ เจนเจพเจ‚: เจญเจพเจ—เฉ€เจฆเจพเจฐ เจจเฉ‚เฉฐ เจ†เจชเจฃเฉ‡ เจจเจฟเฉฑเจœเฉ€ เจ–เจพเจคเฉ‡ 'เจคเฉ‡ เจœเจพเจฃ เจฆเฉ€ เจฒเฉ‹เฉœ เจนเฉเฉฐเจฆเฉ€ เจนเฉˆ, "เจšเฉˆเฉฑเจ•" เจฌเจŸเจจ 'เจคเฉ‡ เจ•เจฒเจฟเฉฑเจ• เจ•เจฐเฉ‹, เจ…เจคเฉ‡ เจ•เฉเจ เจธเจฎเฉ‡เจ‚ เจฌเจพเจ…เจฆ เจ‰เจธ เจจเฉ‡ เจœเฉ‹ เจ•เฉ€เจคเจพ เจ‰เจธ 'เจคเฉ‡ เจ•เจฟเจธเฉ‡ เจ•เจฟเจธเจฎ เจฆเจพ เจตเจฟเจธเจคเฉเจฐเจฟเจค เจซเฉ€เจกเจฌเฉˆเจ• เจฆเฉ‡เจ–เจฆเจพ เจนเฉˆเฅค เจ…เจคเฉ‡ เจ‡เจน เจ‡เจธ เจชเจฒ 'เจคเฉ‡ เจนเฉˆ เจ•เจฟ เจ…เจธเฉ€เจ‚ เจ†เจชเจฃเฉ€ เจธเจฎเฉฑเจธเจฟเจ† เจตเฉฑเจฒ เจœเจพเจฃเจพ เจธเจผเฉเจฐเฉ‚ เจ•เจฐเจฆเฉ‡ เจนเจพเจ‚.

เจ‡เจธ เจฒเฉˆเจฌ เจฆเฉ€ เจคเจธเจฆเฉ€เจ• เจ‡เจธ เจคเจฐเฉเจนเจพเจ‚ เจ•เฉ€เจคเฉ€ เจ—เจˆ เจนเฉˆ: เจ…เจธเฉ€เจ‚ เจญเจพเจ—เฉ€เจฆเจพเจฐ เจฆเฉ‡ เจ•เจพเจซเจ•เจพ เจจเฉ‚เฉฐ เจ‡เฉฑเจ• เจจเจฟเจฏเฉฐเจคเจฐเจฃ เจกเฉ‡เจŸเจพ เจชเฉˆเจ•เฉ‡เจŸ เจญเฉ‡เจœเจฆเฉ‡ เจนเจพเจ‚, เจซเจฟเจฐ เจ—เฉŒเจฌเจฒเจฟเจจ เจ‡เจธ เจกเฉ‡เจŸเจพ เจชเฉˆเจ•เฉ‡เจŸ เจจเฉ‚เฉฐ HDFS เจตเจฟเฉฑเจš เจŸเฉเจฐเจพเจ‚เจธเจซเจฐ เจ•เจฐเจฆเจพ เจนเฉˆ, เจซเจฟเจฐ เจเจ…เจฐเจซเจฒเฉ‹ เจ‡เจธ เจกเฉ‡เจŸเจพ เจชเฉˆเจ•เฉ‡เจŸ เจจเฉ‚เฉฐ เจฒเฉˆเจ‚เจฆเจพ เจนเฉˆ เจ…เจคเฉ‡ เจ‡เจธเจจเฉ‚เฉฐ เจ•เจฒเจฟเจ•เจนเจพเจŠเจธ เจตเจฟเฉฑเจš เจฐเฉฑเจ–เจฆเจพ เจนเฉˆเฅค เจšเจพเจฒ เจ‡เจน เจนเฉˆ เจ•เจฟ เจเจ…เจฐเจซเจฒเฉ‹ เจจเฉ‚เฉฐ เจ‡เจน เจ…เจธเจฒ เจธเจฎเฉ‡เจ‚ เจตเจฟเฉฑเจš เจจเจนเฉ€เจ‚ เจ•เจฐเจจเจพ เจชเฉˆเจ‚เจฆเจพ, เจ‡เจน เจ‡เฉฑเจ• เจ…เจจเฉเจธเฉ‚เจšเฉ€ เจฆเฉ‡ เจ…เจจเฉเจธเจพเจฐ เจ•เจฐเจฆเจพ เจนเฉˆ: เจนเจฐ 15 เจฎเจฟเฉฐเจŸ เจตเจฟเฉฑเจš เจ‡เจน เจซเจพเจˆเจฒเจพเจ‚ เจฆเจพ เจ‡เฉฑเจ• เจธเจฎเฉ‚เจน เจฒเฉˆเจ‚เจฆเจพ เจนเฉˆ เจ…เจคเฉ‡ เจ‰เจนเจจเจพเจ‚ เจจเฉ‚เฉฐ เจ…เจชเจฒเฉ‹เจก เจ•เจฐเจฆเจพ เจนเฉˆเฅค

เจ‡เจน เจชเจคเจพ เจšเจฒเจฆเจพ เจนเฉˆ เจ•เจฟ เจธเจพเจจเฉ‚เฉฐ เจ†เจชเจฃเฉ€ เจฌเฉ‡เจจเจคเฉ€ 'เจคเฉ‡ เจ‰เจจเฉเจนเจพเจ‚ เจฆเฉ‡ เจกเฉ€เจเจœเฉ€ เจจเฉ‚เฉฐ เจ†เจชเจฃเฉ‡ เจ†เจช เจŸเจฐเจฟเฉฑเจ—เจฐ เจ•เจฐเจจ เจฆเฉ€ เจœเจผเจฐเฉ‚เจฐเจค เจนเฉˆ เจœเจฆเฉ‹เจ‚ เจ•เจฟ เจšเฉˆเจ•เจฐ เจ‡เฉฑเจฅเฉ‡ เจ…เจคเฉ‡ เจนเฉเจฃ เจšเฉฑเจฒ เจฐเจฟเจนเจพ เจนเฉˆเฅค เจ—เฉ‚เจ—เจฒเจฟเฉฐเจ— เจคเฉ‹เจ‚ เจฌเจพเจ…เจฆ, เจธเจพเจจเฉ‚เฉฐ เจชเจคเจพ เจฒเฉฑเจ—เจพ เจ•เจฟ เจเจ…เจฐเจซเจฒเฉ‹ เจฆเฉ‡ เจฌเจพเจ…เจฆ เจฆเฉ‡ เจธเฉฐเจธเจ•เจฐเจฃเจพเจ‚ เจฒเจˆ เจ‡เฉฑเจ• เจ…เจ–เฉŒเจคเฉ€ เจนเฉˆ เจชเฉเจฐเจฏเฉ‹เจ—เจพเจคเจฎเจ• 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'

เจฌเฉ‡เจจเจคเฉ€ 'เจคเฉ‡ เจธเจซเจฒเจคเจพเจชเฉ‚เจฐเจตเจ• เจชเฉเจฐเจ•เจฟเจฐเจฟเจ† เจ•เฉ€เจคเฉ€ เจ—เจˆ เจธเฉ€เฅค

เจ‡เจธ เจ…เจจเฉเจธเจพเจฐ, เจ…เจธเฉ€เจ‚ เจซเจฟเจฐ เจกเฉ€เจเจœเฉ€ เจจเฉ‚เฉฐ เจ•เจพเจฐเจตเจพเจˆ เจ•เจฐเจจ เจ…เจคเฉ‡ เจ•เจฒเจฟเจ•เจนเจพเจŠเจธ เจŸเฉ‡เจฌเจฒ เจจเฉ‚เฉฐ เจฌเฉ‡เจจเจคเฉ€ เจ•เจฐเจจ เจฒเจˆ เจ•เฉเจ เจธเจฎเจพเจ‚ เจฆเจฟเฉฐเจฆเฉ‡ เจนเจพเจ‚, เจ•เฉฐเจŸเจฐเฉ‹เจฒ เจกเฉ‡เจŸเจพ เจชเฉˆเจ•เฉ‡เจŸ เจจเฉ‚เฉฐ เจซเฉœเจจ เจฆเฉ€ เจ•เฉ‹เจธเจผเจฟเจธเจผ เจ•เจฐเจฆเฉ‡ เจนเฉ‹เจเฅค

เจœเจพเจ‚เจš เจชเฉ‚เจฐเฉ€ เจนเฉ‹เจˆเฅค

เจธเจฐเฉ‹เจค: www.habr.com

เจ‡เฉฑเจ• เจŸเจฟเฉฑเจชเจฃเฉ€ เจœเฉ‹เฉœเฉ‹