āĻĒāϰ⧀āĻ•ā§āώāĻžāĻŽā§‚āϞāĻ• API āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ āĻāϝāĻŧāĻžāϰāĻĢā§āϞ⧋āϤ⧇ āϕ⧀āĻ­āĻžāĻŦ⧇ āĻāĻ•āϟāĻŋ DAG āĻŸā§āϰāĻŋāĻ—āĻžāϰ āϤ⧈āϰāĻŋ āĻ•āϰāĻŦ⧇āύ

āφāĻŽāĻžāĻĻ⧇āϰ āĻļāĻŋāĻ•ā§āώāĻžāĻŽā§‚āϞāĻ• āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽāϗ⧁āϞāĻŋ āĻĒā§āϰāĻ¸ā§āϤ⧁āϤ āĻ•āϰāĻžāϰ āϏāĻŽāϝāĻŧ, āφāĻŽāϰāĻž āύāĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āϟ āϏāϰāĻžā§āϜāĻžāĻŽāϗ⧁āϞāĻŋāϰ āϏāĻžāĻĨ⧇ āĻ•āĻžāϜ āĻ•āϰāĻžāϰ āĻ•ā§āώ⧇āĻ¤ā§āϰ⧇ āĻĒāĻ°ā§āϝāĻžāϝāĻŧāĻ•ā§āϰāĻŽā§‡ āϏāĻŽāĻ¸ā§āϝāĻžāϰ āϏāĻŽā§āĻŽā§āĻ–ā§€āύ āĻšāχāĨ¤ āĻāĻŦāĻ‚ āĻāχ āĻŽā§āĻšā§āĻ°ā§āϤ⧇ āϝāĻ–āύ āφāĻŽāϰāĻž āϤāĻžāĻĻ⧇āϰ āĻŽā§āĻ–ā§‹āĻŽā§āĻ–āĻŋ āĻšāχ, āϏ⧇āĻ–āĻžāύ⧇ āϏāĻ°ā§āĻŦāĻĻāĻž āϝāĻĨ⧇āĻˇā§āϟ āĻĄāϕ⧁āĻŽā§‡āĻ¨ā§āĻŸā§‡āĻļāύ āĻāĻŦāĻ‚ āύāĻŋāĻŦāĻ¨ā§āϧ āĻĨāĻžāϕ⧇ āύāĻž āϝāĻž āφāĻŽāĻžāĻĻ⧇āϰ āĻāχ āϏāĻŽāĻ¸ā§āϝāĻžāϟāĻŋ āĻŽā§‹āĻ•āĻžāĻŦ⧇āϞāĻž āĻ•āϰāϤ⧇ āϏāĻžāĻšāĻžāĻ¯ā§āϝ āĻ•āϰāĻŦ⧇āĨ¤

āĻāϟāĻŋ āĻ›āĻŋāϞ, āωāĻĻāĻžāĻšāϰāĻŖāĻ¸ā§āĻŦāϰ⧂āĻĒ, 2015 āϏāĻžāϞ⧇, āĻāĻŦāĻ‚ "āĻŦāĻŋāĻ— āĻĄā§‡āϟāĻž āĻ¸ā§āĻĒ⧇āĻļāĻžāϞāĻŋāĻ¸ā§āϟ" āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽā§‡āϰ āϏāĻŽāϝāĻŧ āφāĻŽāϰāĻž 35 āϜāύ āĻāĻ•āϝ⧋āϗ⧇ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀āϰ āϜāĻ¨ā§āϝ āĻ¸ā§āĻĒāĻžāĻ°ā§āĻ• āϏāĻš āĻāĻ•āϟāĻŋ āĻšā§āϝāĻžāĻĄā§āĻĒ āĻ•ā§āϞāĻžāĻ¸ā§āϟāĻžāϰ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇āĻ›āĻŋāĨ¤ āχāϝāĻŧāĻžāĻ°ā§āύ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ āĻāχ āϧāϰāύ⧇āϰ āĻŦā§āϝāĻŦāĻšāĻžāϰ⧇āϰ āĻ•ā§āώ⧇āĻ¤ā§āϰ⧇ āϕ⧀āĻ­āĻžāĻŦ⧇ āĻāϟāĻŋ āĻĒā§āϰāĻ¸ā§āϤ⧁āϤ āĻ•āϰāĻž āϝāĻžāϝāĻŧ āϤāĻž āĻĒāϰāĻŋāĻˇā§āĻ•āĻžāϰ āĻ›āĻŋāϞ āύāĻžāĨ¤ āĻļ⧇āώ āĻĒāĻ°ā§āϝāĻ¨ā§āϤ, āĻāϟāĻŋ āϖ⧁āρāĻœā§‡ āĻŦ⧇āϰ āĻ•āϰ⧇ āĻāĻŦāĻ‚ āφāĻŽāĻžāĻĻ⧇āϰ āύāĻŋāϜāĻ¸ā§āĻŦ āĻĒāĻĨ⧇ āĻšāĻžāρāϟāĻž, āφāĻŽāϰāĻž āϤāĻž āĻ•āϰ⧇āĻ›āĻŋ HabrÊ āωāĻĒāϰ āĻĒā§‹āĻ¸ā§āϟ āĻāĻŦāĻ‚ āĻ āϏāĻžā§āϚāĻžāϞāĻŋāϤ āĻŽāĻ¸ā§āϕ⧋ āĻ¸ā§āĻĒāĻžāĻ°ā§āĻ• āĻŽāĻŋāϟāφāĻĒ.

āĻĒā§āϰāĻžāĻ—āϐāϤāĻŋāĻšāĻžāϏāĻŋāĻ•

āĻāĻŦāĻžāϰ āφāĻŽāϰāĻž āĻāĻ•āϟāĻŋ āĻ­āĻŋāĻ¨ā§āύ āĻ•āĻ°ā§āĻŽāϏ⧂āϚāĻŋ āύāĻŋāϝāĻŧ⧇ āĻ•āĻĨāĻž āĻŦāϞāĻŦ- āĻĄā§‡āϟāĻž āχāĻžā§āϜāĻŋāύāĻŋāϝāĻŧāĻžāϰ. āφāĻŽāĻžāĻĻ⧇āϰ āĻ…āĻ‚āĻļāĻ—ā§āϰāĻšāĻŖāĻ•āĻžāϰ⧀āϰāĻž āĻāϟāĻŋāϤ⧇ āĻĻ⧁āϟāĻŋ āϧāϰāϪ⧇āϰ āĻ¸ā§āĻĨāĻžāĻĒāĻ¤ā§āϝ āϤ⧈āϰāĻŋ āĻ•āϰ⧇: āĻ˛ā§āϝāĻžāĻŽā§āĻŦāĻĻāĻž āĻāĻŦāĻ‚ āĻ•āĻžāĻĒāĻžāĨ¤ āĻāĻŦāĻ‚ lamdba āφāĻ°ā§āĻ•āĻŋāĻŸā§‡āĻ•āϚāĻžāϰ⧇, āĻŦā§āϝāĻžāϚ āĻĒā§āϰāĻ•ā§āϰāĻŋāϝāĻŧāĻžāĻ•āϰāϪ⧇āϰ āĻ…āĻ‚āĻļ āĻšāĻŋāϏāĻžāĻŦ⧇, āĻāϝāĻŧāĻžāϰāĻĢā§āϞ⧋ HDFS āĻĨ⧇āϕ⧇ āĻ•ā§āϞāĻŋāĻ• āĻšāĻžāωāϏ⧇ āϞāĻ— āĻ¸ā§āĻĨāĻžāύāĻžāĻ¨ā§āϤāϰ āĻ•āϰāϤ⧇ āĻŦā§āϝāĻŦāĻšā§ƒāϤ āĻšāϝāĻŧāĨ¤

āϏāĻŦāĻ•āĻŋāϛ⧁āχ āϏāĻžāϧāĻžāϰāĻŖāϤ āĻ­āĻžāϞ⧋āĨ¤ āϤāĻžāĻĻ⧇āϰ āύāĻŋāϜāĻ¸ā§āĻŦ āĻĒāĻžāχāĻĒāϞāĻžāχāύ āϤ⧈āϰāĻŋ āĻ•āϰāϤ⧇ āĻĻāĻŋāύāĨ¤ āϝāĻžāχāĻšā§‹āĻ•, āĻāĻ•āϟāĻŋ āĻ•āĻŋāĻ¨ā§āϤ⧁ āφāϛ⧇: āφāĻŽāĻžāĻĻ⧇āϰ āϏāĻŽāĻ¸ā§āϤ āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽ āĻļ⧇āĻ–āĻžāϰ āĻĒā§āϰāĻ•ā§āϰāĻŋāϝāĻŧāĻžāϰ āĻĻ⧃āĻˇā§āϟāĻŋāϕ⧋āĻŖ āĻĨ⧇āϕ⧇ āĻĒā§āϰāϝ⧁āĻ•ā§āϤāĻŋāĻ—āϤāĻ­āĻžāĻŦ⧇ āωāĻ¨ā§āύāϤāĨ¤ āĻ˛ā§āϝāĻžāĻŦ āĻšā§‡āĻ• āĻ•āϰāĻžāϰ āϜāĻ¨ā§āϝ, āφāĻŽāϰāĻž āĻ¸ā§āĻŦāϝāĻŧāĻ‚āĻ•ā§āϰāĻŋāϝāĻŧ āĻšā§‡āĻ•āĻžāϰ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻŋ: āĻ…āĻ‚āĻļāĻ—ā§āϰāĻšāĻŖāĻ•āĻžāϰ⧀āϕ⧇ āϤāĻžāϰ āĻŦā§āϝāĻ•ā§āϤāĻŋāĻ—āϤ āĻ…ā§āϝāĻžāĻ•āĻžāωāĻ¨ā§āĻŸā§‡ āϝ⧇āϤ⧇ āĻšāĻŦ⧇, "āĻšā§‡āĻ•" āĻŦā§‹āϤāĻžāĻŽā§‡ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰāϤ⧇ āĻšāĻŦ⧇ āĻāĻŦāĻ‚ āĻ•āĻŋāϛ⧁ āϏāĻŽāϝāĻŧ⧇āϰ āĻĒāϰ⧇ āϏ⧇ āϝāĻž āĻ•āϰ⧇āϛ⧇ āϤāĻžāϰ āωāĻĒāϰ āĻ•āĻŋāϛ⧁ āĻŦāĻ°ā§āϧāĻŋāϤ āĻĒā§āϰāϤāĻŋāĻ•ā§āϰāĻŋāϝāĻŧāĻž āĻĻ⧇āĻ–āϤ⧇ āĻĒāĻžāĻŦ⧇āĨ¤ āĻāĻŦāĻ‚ āĻāχ āĻŽā§āĻšā§āĻ°ā§āϤ⧇ āφāĻŽāϰāĻž āφāĻŽāĻžāĻĻ⧇āϰ āϏāĻŽāĻ¸ā§āϝāĻžāϰ āĻ•āĻžāϛ⧇ āϝ⧇āϤ⧇ āĻļ⧁āϰ⧁ āĻ•āϰāĻŋāĨ¤

āĻāχ āĻ˛ā§āϝāĻžāĻŦ⧇āϰ āϝāĻžāϚāĻžāχāĻ•āϰāĻŖāϟāĻŋ āĻāχāĻ­āĻžāĻŦ⧇ āĻ—āĻ āĻŋāϤ: āφāĻŽāϰāĻž āĻ…āĻ‚āĻļāĻ—ā§āϰāĻšāĻŖāĻ•āĻžāϰ⧀āϰ āĻ•āĻžāĻĢāĻ•āĻžāϕ⧇ āĻāĻ•āϟāĻŋ āĻ•āĻ¨ā§āĻŸā§āϰ⧋āϞ āĻĄā§‡āϟāĻž āĻĒā§āϝāĻžāϕ⧇āϟ āĻĒāĻžāĻ āĻžāχ, āϤāĻžāϰāĻĒāϰ āĻ—āĻŦāϞāĻŋāύ āĻāχ āĻĄā§‡āϟāĻž āĻĒā§āϝāĻžāϕ⧇āϟāϟāĻŋ HDFS-āĻ āĻ¸ā§āĻĨāĻžāύāĻžāĻ¨ā§āϤāϰ āĻ•āϰ⧇, āϤāĻžāϰāĻĒāϰ Airflow āĻāχ āĻĄā§‡āϟāĻž āĻĒā§āϝāĻžāϕ⧇āϟāϟāĻŋ āύāĻŋāϝāĻŧ⧇ āĻ•ā§āϞāĻŋāĻ• āĻšāĻžāωāϏ⧇ āϰāĻžāϖ⧇āĨ¤ āĻ•ā§ŒāĻļāϞāϟāĻŋ āĻšāϞ āϝ⧇ āĻāϝāĻŧāĻžāϰāĻĢā§āϞ⧋āϕ⧇ āϰāĻŋāϝāĻŧ⧇āϞ āϟāĻžāχāĻŽā§‡ āĻāϟāĻŋ āĻ•āϰāϤ⧇ āĻšāĻŦ⧇ āύāĻž, āĻāϟāĻŋ āĻāĻ•āϟāĻŋ āϏāĻŽāϝāĻŧāϏ⧂āĻšā§€ āĻ…āύ⧁āϏāĻžāϰ⧇ āĻāϟāĻŋ āĻ•āϰ⧇: āĻĒā§āϰāϤāĻŋ 15 āĻŽāĻŋāύāĻŋāĻŸā§‡ āĻāϟāĻŋ āĻāĻ•āϗ⧁āĻšā§āĻ› āĻĢāĻžāχāϞ āύ⧇āϝāĻŧ āĻāĻŦāĻ‚ āϏ⧇āϗ⧁āϞāĻŋ āφāĻĒāϞ⧋āĻĄ āĻ•āϰ⧇āĨ¤

āĻĻ⧇āĻ–āĻž āϝāĻžāĻšā§āϛ⧇ āϝ⧇ āĻšā§‡āĻ•āĻžāϰ āĻāĻ–āĻžāύ⧇ āĻāĻŦāĻ‚ āĻāĻ–āύ āϚāϞāϛ⧇ āϤāĻ–āύ āφāĻŽāĻžāĻĻ⧇āϰ āĻ…āύ⧁āϰ⧋āϧ⧇ āϤāĻžāĻĻ⧇āϰ āĻĄāĻŋāĻāϜāĻŋāϕ⧇ āύāĻŋāĻœā§‡āĻĻ⧇āϰāϕ⧇ āĻŸā§āϰāĻŋāĻ—āĻžāϰ āĻ•āϰāϤ⧇ āĻšāĻŦ⧇āĨ¤ āϗ⧁āĻ—āϞāĻŋāĻ‚āϝāĻŧ⧇āϰ āĻĒāϰ⧇, āφāĻŽāϰāĻž āϖ⧁āρāĻœā§‡ āĻĒ⧇āϝāĻŧ⧇āĻ›āĻŋ āϝ⧇ āĻāϝāĻŧāĻžāϰāĻĢā§āϞ⧋ āĻāϰ āĻĒāϰāĻŦāĻ°ā§āϤ⧀ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖāϗ⧁āϞāĻŋāϰ āϜāĻ¨ā§āϝ āĻāĻ•āϟāĻŋ āϤāĻĨāĻžāĻ•āĻĨāĻŋāϤ āϰāϝāĻŧ⧇āϛ⧇ āĻĒāϰ⧀āĻ•ā§āώāĻžāĻŽā§‚āϞāĻ• APIāĨ¤ āĻļāĻŦā§āĻĻ experimental, āĻ…āĻŦāĻļā§āϝāχ, āĻāϟāĻž āĻ­ā§€āϤāĻŋāĻ•āϰ āĻļā§‹āύāĻžāĻšā§āϛ⧇, āĻ•āĻŋāĻ¨ā§āϤ⧁ āĻ•āĻŋ āĻ•āϰāĻŦ... āĻšāĻ āĻžā§Ž āĻ•āϰ⧇āχ āϤāĻž āĻŦāĻ¨ā§āϧ āĻšāϝāĻŧ⧇ āϝāĻžāϝāĻŧāĨ¤

ДаĐģĐĩĐĩ ĐžĐŋĐ¸ŅˆĐĩĐŧ вĐĩҁҌ ĐŋŅƒŅ‚ŅŒ: ĐžŅ‚ ŅƒŅŅ‚Đ°ĐŊОвĐēи Airflow Đ´Đž Ņ„ĐžŅ€ĐŧĐ¸Ņ€ĐžĐ˛Đ°ĐŊĐ¸Ņ POST-СаĐŋŅ€ĐžŅĐ°, ĐēĐžŅ‚ĐžŅ€Ņ‹Đš Ņ‚Ņ€Đ¸ĐŗĐŗĐĩŅ€Đ¸Ņ‚ DAG, Đ¸ŅĐŋĐžĐģŅŒĐˇŅƒŅ Experimental API. Đ Đ°ĐąĐžŅ‚Đ°Ņ‚ŅŒ ĐąŅƒĐ´ĐĩĐŧ ҁ Ubuntu 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-āĻ āĻāĻ•āϟāĻŋ āĻŦā§āϰāĻžāωāϜāĻžāϰ⧇ āĻ“āϝāĻŧ⧇āĻŦ āχāĻ¨ā§āϟāĻžāϰāĻĢ⧇āϏ⧇ āφāϘāĻžāϤ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āύ āϝ⧇āĻ–āĻžāύ⧇ Airflow āϚāϞāĻ›āĻŋāϞ, āωāĻĻāĻžāĻšāϰāĻŖāĻ¸ā§āĻŦāϰ⧂āĻĒ: <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 āĻ…āύ⧁āϰ⧋āϧ āϚāĻžāϞ⧁ āĻ•āϰ⧁āύ⧎

āĻĒā§‹āĻ¸ā§āϟ āĻ…āύ⧁āϰ⧋āϧ āύāĻŋāĻœā§‡āχ āĻāχ āĻŽāϤ āĻĻ⧇āĻ–āĻžāĻŦ⧇:

>>> 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

DDoS āϏ⧁āϰāĻ•ā§āώāĻž, VPS VDS āϏāĻžāĻ°ā§āĻ­āĻžāϰ āϏāĻš āϏāĻžāχāϟāϗ⧁āϞāĻŋāϰ āϜāĻ¨ā§āϝ āύāĻŋāĻ°ā§āĻ­āϰāϝ⧋āĻ—ā§āϝ āĻšā§‹āĻ¸ā§āϟāĻŋāĻ‚ āĻ•āĻŋāύ⧁āύ đŸ”Ĩ DDoS āϏ⧁āϰāĻ•ā§āώāĻž āϏāĻš āύāĻŋāĻ°ā§āĻ­āϰāϝ⧋āĻ—ā§āϝ āĻ“āϝāĻŧ⧇āĻŦāϏāĻžāχāϟ āĻšā§‹āĻ¸ā§āϟāĻŋāĻ‚ āĻ•āĻŋāύ⧁āύ, VPS VDS āϏāĻžāĻ°ā§āĻ­āĻžāϰ | ProHoster