Search code examples
pythonflaskherokuflask-restful

im trying to host my flask api on heroku, but when passing the path to my app, i get an import error


the error im getting: ImportError: attempted relative import with no known parent package

My folder structure:

-Backend

  • __init__.py
  • run.py
  • procfile

__init.py:

has the create app method

run.py:

from . import create_app

if __name__ == "__main__":
   app = create_app("config")
   app.run(debug=True)

procfile:

web: gunicorn run:app

EDIT:

I rearranged the app structure by which:

  • Backend
  • init.py
  • procifle
  • extensions.py
  • src
  • init.py
  • run.py

init.py:

empty

src/init.py:

from ..extensions import db,migrate
has the create app method

src/run.py:

from src import create_app

if __name__ == "__main__":
  app = create_app("config")
  app.run(debug=True)

so now the new error is:

  • from ..extensions import db
  • ImportError: attempted relative import beyond top-level package

Edit #2: another thing to point out is, that suppose in the run.py i do the following: from Backend import create_app()

I get the following error: no module named "Backend" why could that be?

Has anyone faced a similar issue and what can I do to solve it?


Solution

  • Update based on new information I think we can get you home.

    1.) Move run.py next to the procfile (same dir). That "run file" should be in that top level dit at /app/run.py in Heroku.

    A good basic pattern for file organization is to "module" everything (a dir with a __init__.py file). Then all imports are from the top level run.py [where the process is running from] walking subfolders. As long as you traverse down into imports things stay pretty stable. If you are trying to navigate up dirs it becomes problematic.

    Resolve any imports, it can be tricky at first but soon becomes a way of thinking.

    2.) Move extensions.py into src (for now) and import from src import foo

    The following is the pattern in all my active Django and similar apps running in Heroku. Same layout I have been using for many years. In the following screenshot manage.py is the Django equivalent of your run.py. I am not using the docker image on this app, so that is not in the equation, just code and dependencies.

    Screen grab of my Django dir sent to Heroku

    Your problems are totally understandable, it's easy to take for granted all the times other Python devs do this.