13

I haven't been able to move common code outside of the dag directory that airflow uses. I've looked in the airflow source and found imp.load_source.

Is it possible to use imp.load_source to load modules that exist outside of the dag directory? In the example below this would be importing either foo or bar from the common directory.

── airflow_home
     |──── dags
     │   ├── dag_1.py
     │   └── dag_2.py
     ├── common
         ├── foo.py
         └── bar.py
cameres
  • 498
  • 2
  • 5
  • 15
  • does all these folders part of same app-module? or different modules. just in case all are from same app module you can use relative path to import. – Hara Jul 13 '17 at 03:03
  • @Haranadh yes. I updated the diagram to show the airflow_home directory. – cameres Jul 13 '17 at 05:30
  • I could not answer in comments. I posted my detailed answer. if you like it. please upvote. :) – Hara Jul 13 '17 at 06:00
  • A workaround by modifying the PYTHONPATH is posted here: https://stackoverflow.com/a/48154139/1881080 – cameres May 29 '18 at 15:08

5 Answers5

10

Just add __init__.py files in all 3 folders. it should work. Infact every folder in my folder structure having __init__.py. I could run the code and see output.

Example folder structure could be as:

── airflow_home
     ├── __init__.py
     |──── dags
     │   ├── __init__.py
     │   ├── dag_1.py
     │   └── dag_2.py
     ├── common
         ├── __init__.py
         ├── foo.py
         └── bar.py

and dag_1.py code can be as:

from stackoverflow.src.questions.airflow_home.common.bar import bar_test

def main():
    bar_test()

main()

I'm running this piece of code from my pycharm. Your airflow_home's folder path in my pycharm is stackoverflow/src/questions/airflow_home/

And bar.py code is

def bar_test():
    print "bar hara"
palerdot
  • 7,416
  • 5
  • 41
  • 47
Hara
  • 1,467
  • 4
  • 18
  • 35
  • 1
    mine airflow home path is /usr/local/airflow... the from statement is like: "from usr.local.airflow" ... It claims an error "no module name usr". What should I do? – Julinho da Adelaide Jul 17 '18 at 04:44
7

Other way instead of adding __init__.py file is to add the following include at the top of dag script:

import sys
import os
sys.path.insert(0,os.path.abspath(os.path.dirname(__file__)))
Nguyen Van Duc
  • 1,019
  • 10
  • 9
7

Add your airflow home path to PYTHONPATH

export AIRFLOW_HOME=/usr/local/airflow
export PYTHONPATH="${PYTHONPATH}:${AIRFLOW_HOME}"

Dockerfile

ENV AIRFLOW_HOME=/usr/local/airflow
ENV PYTHONPATH "${PYTHONPATH}:${AIRFLOW_HOME}"
Haresh Chhelana
  • 24,720
  • 5
  • 57
  • 67
1

This works for me, I'm running airflow on docker by the way:

import sys
import os
sys.path.append(os.path.abspath(os.environ["AIRFLOW_HOME"]))
Alexander L. Hayes
  • 3,892
  • 4
  • 13
  • 34
0

After running into the same problem, this fixed it for me:

import sys, os sys.path.insert(0,os.path.abspath(os.path.join(os.path.dirname(file),os.path.pardir))) from common.foo import *

Nick Weimer
  • 497
  • 5
  • 7