рдкреНрд░рдпреЛрдЧрд╛рддреНрдордХ API рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рдПрдпрд░рдлреНрд▓реЛрдорд╛ DAG рдЯреНрд░рд┐рдЧрд░ рдХрд╕рд░реА рдмрдирд╛рдЙрдиреЗ

рд╣рд╛рдореНрд░рд╛ рд╢реИрдХреНрд╖рд┐рдХ рдХрд╛рд░реНрдпрдХреНрд░рдорд╣рд░реВ рддрдпрд╛рд░ рдЧрд░реНрджрд╛, рд╣рд╛рдореАрд▓реЗ рдЖрд╡рдзрд┐рдХ рд░реВрдкрдорд╛ рдХреЗрд╣реА рдЙрдкрдХрд░рдгрд╣рд░реВрд╕рдБрдЧ рдХрд╛рдо рдЧрд░реНрдиреЗ рд╕рдиреНрджрд░реНрднрдорд╛ рдХрдард┐рдирд╛рдЗрд╣рд░реВрдХреЛ рд╕рд╛рдордирд╛ рдЧрд░реНрдЫреМрдВред рд░ рдпрд╕ рдХреНрд╖рдгрдорд╛ рдЬрдм рд╣рд╛рдореА рддрд┐рдиреАрд╣рд░реВрд╕рдБрдЧ рднреЗрдЯреНрдЫреМрдВ, рддреНрдпрд╣рд╛рдБ рд╕рдзреИрдВ рдкрд░реНрдпрд╛рдкреНрдд рдХрд╛рдЧрдЬрд╛рддрд╣рд░реВ рд░ рд▓реЗрдЦрд╣рд░реВ рдЫреИрдирдиреН рдЬреБрди рдпрд╕ рд╕рдорд╕реНрдпрд╛рдХреЛ рд╕рд╛рдордирд╛ рдЧрд░реНрди рдорджреНрджрдд рдЧрд░реНрджрдЫред

рддреНрдпрд╕реЛрднрдП рдпреЛ, рдЙрджрд╛рд╣рд░рдгрдХрд╛ рд▓рд╛рдЧрд┐, 2015 рдорд╛ рдерд┐рдпреЛ, рд░ рд╣рд╛рдореАрд▓реЗ рдмрд┐рдЧ рдбрд╛рдЯрд╛ рд╡рд┐рд╢реЗрд╖рдЬреНрдЮ рдХрд╛рд░реНрдпрдХреНрд░рдордорд╛ 35 рдПрдХ рд╕рд╛рде рдкреНрд░рдпреЛрдЧрдХрд░реНрддрд╛рд╣рд░реВрдХреЛ рд▓рд╛рдЧрд┐ рд╕реНрдкрд╛рд░реНрдХрдХреЛ рд╕рд╛рде Hadoop рдХреНрд▓рд╕реНрдЯрд░ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрдпреМрдВред рдпреЛ рдпрд╛рд░реНрди рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рдпрд╕реНрддреЛ рдкреНрд░рдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗрд╕рдХреЛ рд▓рд╛рдЧрд┐ рдХрд╕рд░реА рддрдпрд╛рд░ рдЧрд░реНрдиреЗ рднрдиреНрдиреЗ рд╕реНрдкрд╖реНрдЯ рдерд┐рдПрдиред рдирддрд┐рдЬрд╛рдХреЛ рд░реВрдкрдорд╛, рддрд┐рдиреАрд╣рд░реВрд▓реЗ рдЖрдлреИрдВрд▓реЗ рдмрд╛рдЯреЛ рдкрддреНрддрд╛ рд▓рдЧрд╛рдПрд░ рд╣рд┐рдБрдбреЗ Habr├й рдорд╛ рдкреЛрд╕реНрдЯ рд░ рдкреНрд░рджрд░реНрд╢рди рдкрдирд┐ рдЧрд░реЗ рдорд╕реНрдХреЛ рд╕реНрдкрд╛рд░реНрдХ рдмреИрдардХ.

рдкреНрд░рд╛рдЧрд┐рддрд┐рд╣рд╛рд╕

рдпрд╕ рдкрдЯрдХ рд╣рд╛рдореА рдлрд░рдХ рдХрд╛рд░реНрдпрдХреНрд░рдордХреЛ рдмрд╛рд░реЗрдорд╛ рдХреБрд░рд╛ рдЧрд░реНрдиреЗрдЫреМрдВ - рдбрд╛рдЯрд╛ рдИрдиреНрдЬрд┐рдирд┐рдпрд░ред рдпрд╕рдорд╛, рд╣рд╛рдореНрд░рд╛ рд╕рд╣рднрд╛рдЧреАрд╣рд░реВрд▓реЗ рджреБрдИ рдкреНрд░рдХрд╛рд░рдХреЛ рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдирд┐рд░реНрдорд╛рдг рдЧрд░реНрдЫрдиреН: рд▓рд╛рдореНрдмреНрдбрд╛ рд░ рдХрд╛рдкрд╛ред рд░ lamdba рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░рдорд╛, Airflow рд▓рд╛рдИ HDFS рдмрд╛рдЯ ClickHouse рдорд╛ рд▓рдЧрд╣рд░реВ рд╕реНрдерд╛рдирд╛рдиреНрддрд░рдг рдЧрд░реНрди рдмреНрдпрд╛рдЪ рдкреНрд░рд╢реЛрдзрдирдХреЛ рднрд╛рдЧрдХреЛ рд░реВрдкрдорд╛ рдкреНрд░рдпреЛрдЧ рдЧрд░рд┐рдиреНрдЫред

рд╕рдмреИ рдХреБрд░рд╛ рд╕рд╛рдорд╛рдиреНрдпрддрдпрд╛ рд░рд╛рдореНрд░реЛ рдЫред рддрд┐рдиреАрд╣рд░реВрдХреЛ рдкрд╛рдЗрдкрд▓рд╛рдЗрдирд╣рд░реВ рдирд┐рд░реНрдорд╛рдг рдЧрд░реНрди рджрд┐рдиреБрд╣реЛрд╕реНред рдпрджреНрдпрдкрд┐, рддреНрдпрд╣рд╛рдБ рдПрдЙрдЯрд╛ "рддрд░" рдЫ: рд╣рд╛рдореНрд░рд╛ рд╕рдмреИ рдХрд╛рд░реНрдпрдХреНрд░рдорд╣рд░реВ рдкреНрд░рд╛рд╡рд┐рдзрд┐рдХ рд░реВрдкрдорд╛ рд╕рд┐рдХрд╛рдЗ рдкреНрд░рдХреНрд░рд┐рдпрд╛рдХреИ рд╕рдиреНрджрд░реНрднрдорд╛ рдЙрдиреНрдирдд рдЫрдиреНред рдкреНрд░рдпреЛрдЧрд╢рд╛рд▓рд╛ рдЬрд╛рдБрдЪ рдЧрд░реНрди, рд╣рд╛рдореА рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдЬрд╛рдБрдЪрдХрд░реНрддрд╛рд╣рд░реВ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрдЫреМрдВ: рд╕рд╣рднрд╛рдЧреАрд▓реЗ рдЖрдлреНрдиреЛ рд╡реНрдпрдХреНрддрд┐рдЧрдд рдЦрд╛рддрд╛рдорд╛ рдЬрд╛рдиреБ рдкрд░реНрдЫ, "рдЬрд╛рдБрдЪ" рдмрдЯрдирдорд╛ рдХреНрд▓рд┐рдХ рдЧрд░реНрдиреБрд╣реЛрд╕реН, рд░ рдХреЗрд╣реА рд╕рдордп рдкрдЫрд┐ рдЙрд╕рд▓реЗ рдХреЗ рдЧрд░реЗрдХреЛрдорд╛ рдХреЗрд╣реА рдкреНрд░рдХрд╛рд░рдХреЛ рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рджреЗрдЦреНрдЫред рд░ рдпреЛ рдпрд╕ рдмрд┐рдиреНрджреБрдорд╛ рд╣реЛ рдХрд┐ рд╣рд╛рдореА рд╣рд╛рдореНрд░реЛ рд╕рдорд╕реНрдпрд╛рдорд╛ рдкреБрдЧреНрди рдерд╛рд▓реНрдЫреМрдВред

рдпреЛ рд▓реНрдпрд╛рдм рдЬрд╛рдБрдЪ рдЧрд░реНрджреИ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдЧрд░рд┐рдПрдХреЛ рдЫ: рд╣рд╛рдореА рд╕рд╣рднрд╛рдЧреАрдХреЛ рдХрд╛рдлреНрдХрд╛рд▓рд╛рдИ рдирд┐рдпрдиреНрддреНрд░рдг рдбреЗрдЯрд╛ рдкреНрдпрд╛рдХреЗрдЯ рдкрдард╛рдЙрдБрдЫреМрдВ, рддреНрдпрд╕рдкрдЫрд┐ Gobblin рд▓реЗ рдпреЛ рдбреЗрдЯрд╛ рдкреНрдпрд╛рдХреЗрдЯ HDFS рдорд╛ рд╕реНрдерд╛рдирд╛рдиреНрддрд░рдг рдЧрд░реНрдЫ, рддреНрдпрд╕рдкрдЫрд┐ Airflow рд▓реЗ рдпреЛ рдбреЗрдЯрд╛ рдкреНрдпрд╛рдХреЗрдЯ рд▓рд┐рдиреНрдЫ рд░ рдпрд╕рд▓рд╛рдИ ClickHouse рдорд╛ рд░рд╛рдЦреНрдЫред рдЪрд╛рд▓ рдпреЛ рд╣реЛ рдХрд┐ Airflow рд▓реЗ рдпреЛ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╕рдордпрдорд╛ рдЧрд░реНрдиреБ рдкрд░реНрджреИрди, рдпреЛ рд╕рдордп рддрд╛рд▓рд┐рдХрд╛рдорд╛ рдЧрд░реНрдЫ: рдПрдХ рдкрдЯрдХ рдкреНрд░рддреНрдпреЗрдХ 15 рдорд┐рдиреЗрдЯрдорд╛ рдпрд╕рд▓реЗ рдлрд╛рдЗрд▓рд╣рд░реВрдХреЛ рдЧреБрдЪреНрдЫрд╛ рд▓рд┐рдиреНрдЫ рд░ рддрд┐рдиреАрд╣рд░реВрд▓рд╛рдИ рдЕрдкрд▓реЛрдб рдЧрд░реНрджрдЫред

рдпреЛ рдмрд╛рд╣рд┐рд░ рдЬрд╛рдиреНрдЫ рдХрд┐ рд╣рд╛рдореАрд▓реЗ рдХреБрдиреИ рди рдХреБрдиреИ рд░реВрдкрдорд╛ рд╣рд╛рдореНрд░реЛ рдЕрдиреБрд░реЛрдзрдорд╛ рддрд┐рдиреАрд╣рд░реВрдХреЛ DAG рдЖрдлреИрдВ рдЯреНрд░рд┐рдЧрд░ рдЧрд░реНрди рдЖрд╡рд╢реНрдпрдХ рдЫ рдЬрдм рдкрд░реАрдХреНрд╖рдХ рдпрд╣рд╛рдБ рд░ рдЕрд╣рд┐рд▓реЗ рдЪрд▓рд┐рд░рд╣реЗрдХреЛ рдЫред рдЧреБрдЧрд▓рд┐рдЩ, рд╣рд╛рдореАрд▓реЗ рдкрддреНрддрд╛ рд▓рдЧрд╛рдпреМрдВ рдХрд┐ рдПрдпрд░рдлреНрд▓реЛрдХреЛ рдкрдЫрд┐рд▓реНрд▓рд╛ рд╕рдВрд╕реНрдХрд░рдгрд╣рд░реВрдХреЛ рд▓рд╛рдЧрд┐ рддреНрдпрд╣рд╛рдБ рддрдерд╛рдХрдерд┐рдд рдЫ рдкреНрд░рдпреЛрдЧрд╛рддреНрдордХ APIред рд╢рдмреНрдж experimental, рдЕрд╡рд╢реНрдп рдкрдирд┐, рдпреЛ рдбрд░рд▓рд╛рдЧреНрджреЛ рд╕реБрдирд┐рдиреНрдЫ, рддрд░ рдХреЗ рдЧрд░реНрдиреЗ ... рдпреЛ рдЕрдЪрд╛рдирдХ рдмрдиреНрдж рд╣реБрдиреНрдЫред

рдЕрд░реНрдХреЛ, рд╣рд╛рдореА рд╕рдореНрдкреВрд░реНрдг рдорд╛рд░реНрдЧрдХреЛ рд╡рд░реНрдгрди рдЧрд░реНрдиреЗрдЫреМрдВ: рдПрдпрд░рдлреНрд▓реЛ рд╕реНрдерд╛рдкрдирд╛ рдЧрд░реНрдиреЗрджреЗрдЦрд┐ рд▓рд┐рдПрд░ рдкреНрд░рд╛рдпреЛрдЧрд┐рдХ API рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ DAG рдЯреНрд░рд┐рдЧрд░ рдЧрд░реНрдиреЗ POST рдЕрдиреБрд░реЛрдз рдЙрддреНрдкрдиреНрди рдЧрд░реНрдиреЗред рд╣рд╛рдореА Ubuntu 16.04 рд╕рдБрдЧ рдХрд╛рдо рдЧрд░реНрдиреЗрдЫреМрдВред

1. рдПрдпрд░рдлреНрд▓реЛ рд╕реНрдерд╛рдкрдирд╛

рд╣рд╛рдореАрд╕рдБрдЧ Python 3 рд░ virtualenv рдЫ рднрдиреЗрд░ рдЬрд╛рдБрдЪ рдЧрд░реМрдВред

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

рдпрджрд┐ рдпреА рдордзреНрдпреЗ рдПрдХ рд╣рд░рд╛рдЗрд░рд╣реЗрдХреЛ рдЫ рднрдиреЗ, рддреНрдпрд╕рдкрдЫрд┐ рдпрд╕рд▓рд╛рдИ рд╕реНрдерд╛рдкрдирд╛ рдЧрд░реНрдиреБрд╣реЛрд╕реНред

рдЕрдм рдПрдЙрдЯрд╛ рдбрд╛рдЗрд░реЗрдХреНрдЯрд░реА рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реМрдВ рдЬрд╕рдорд╛ рд╣рд╛рдореА Airflow рд╕рдБрдЧ рдХрд╛рдо рдЧрд░реНрди рдЬрд╛рд░реА рд░рд╛рдЦреНрдиреЗрдЫреМрдВред

$ 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 рдкреНрд▓рдЧрдЗрдирд╣рд░реВ рдЕрд╡рд╕реНрдерд┐рдд рд╣реБрдиреЗрдЫрдиреНред рдбрд╛рдЗрд░реЗрдХреНрдЯрд░реА рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реЗрдкрдЫрд┐, рд╡рд╛рддрд╛рд╡рд░рдг рдЪрд░ рд╕реЗрдЯ рдЧрд░реНрдиреБрд╣реЛрд╕реН 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 рд╕реНрдерд╛рдкрд┐рдд рдЫ рдХрд┐ рдЫреИрди рдЬрд╛рдБрдЪ рдЧрд░реНрдиреБрд╣реЛрд╕реН:

$ 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

Airflow рд╕рдБрдЧ рд╡реЗрдм рдЗрдиреНрдЯрд░рдлреЗрд╕ рдЫред рдпреЛ рдЖрджреЗрд╢ рдЪрд▓рд╛рдПрд░ рд╕реБрд░реВ рдЧрд░реНрди рд╕рдХрд┐рдиреНрдЫ:

(venv) $ airflow webserver --port 8081

рддрдкрд╛рдИрд▓реЗ рдЕрдм рдмреНрд░рд╛рдЙрдЬрд░рдорд╛ рдкреЛрд░реНрдЯ 8081 рдорд╛ рд╣реЛрд╕реНрдЯрдорд╛ рд╡реЗрдм рдЗрдиреНрдЯрд░рдлреЗрд╕ рдкрд╣реБрдБрдЪ рдЧрд░реНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫ рдЬрд╣рд╛рдБ рдПрдпрд░рдлреНрд▓реЛ рдЪрд▓рд┐рд░рд╣реЗрдХреЛ рдерд┐рдпреЛ, рдЬрд╕реНрддреИ: <hostname:8081>.

реи. рдкреНрд░рдпреЛрдЧрд╛рддреНрдордХ 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

рдПрдХ рдЯрд┐рдкреНрдкрдгреА рдердкреНрди