title: Writing and importing custom plugins in Airflow
body: <p>This is actually two questions combined into one. </p>
  
  <p>My <code>AIRFLOW_HOME</code> is structured like</p>
  
  <pre><code>airflow
  +-- dags
  +-- plugins
      +-- __init__.py
      +-- hooks
          +-- __init__.py
          +-- my_hook.py
          +-- another_hook.py
      +-- operators
          +-- __init__.py
          +-- my_operator.py
          +-- another_operator.py
      +-- sensors
      +-- utils
  </code></pre>
  
  <p>I've been following astronomer.io's examples here <a href="https://github.com/airflow-plugins" rel="noreferrer">https://github.com/airflow-plugins</a>. My custom <code>operators</code> use my custom <code>hooks</code>, and all the imports are relative to the top level folder <code>plugins</code>.</p>
  
  <pre class="lang-py prettyprint-override"><code># my_operator.py
  from plugins.hooks.my_hook import MyHook
  </code></pre>
  
  <p>However, when I tried moving my entire repository into the plugins folder, I get an import error after running <code>airflow list_dags</code> saying that <code>plugins</code> cannot be found.</p>
  
  <p>I read up a little about it and apparently Airflow loads the plugins into its core module so they can be imported like </p>
  
  <pre class="lang-py prettyprint-override"><code># my_operator.py
  from airflow.hooks.my_hook import MyHook
  </code></pre>
  
  <p>So I changed all the imports to read directly from <code>airflow.plugin_type</code> instead. I get another import error though, this time saying that <code>my_hook</code> cannot be found. I restart my workers, scheduler and webserver every time but that doesn't seem to be the issue. I've looked at solutions proposed in similar questions and they don't work either.</p>
  
  <p>The official documentation also shows this way <a href="https://airflow.apache.org/plugins.html" rel="noreferrer">https://airflow.apache.org/plugins.html</a> of extending the <code>AirflowPlugin</code> class, but I'm not sure where this "interface" should reside. I would also prefer a drag and drop option.</p>
  
  <p>Finally, it clearly doesn't make sense for my code repo to be the <code>plugins</code> folder itself, but if I separate them testing becomes inconvenient. Do I have to modify my Airflow configurations to point to my repo every time I run unit tests on my hooks/ops? What are the best practices for testing custom plugins?</p>