Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs
Community Proposals
Community Proposals
tag:snake search within a tag
answers:0 unanswered questions
user:xxxx search by author id
score:0.5 posts with 0.5+ score
"snake oil" exact phrase
votes:4 posts with 4+ votes
created:<1w created < 1 week ago
post_type:xxxx type of post
Search help
Notifications
Mark all as read See all your notifications »
Q&A

Welcome to Software Development on Codidact!

Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.

Comments on Different behavior with relative imports when using flask vs py

Parent

Different behavior with relative imports when using flask vs py

+13
−0

I have a small new Python 3.8 Flask project with some relative import quirks.

For the DB I use SQLAlchemy with Flask-Migrate. My project has the following general structure:

controllers/
static/
templates/
app.py
controller.py
helpers.py
models.py
requirements.txt

The app.py looks like this:

from .controller import app

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=5000, debug=True)

And the controller.py like this:

from flask import Flask
from . import helpers

app = Flask(__name__)
app.config.update(dict(
    SQLALCHEMY_DATABASE_URI = "...",
    SQLALCHEMY_TRACK_MODIFICATIONS = "..."
))
db = SQLAlchemy(app)
migrate = Migrate(app, db)

from .controllers.static_controller import static

app.register_blueprint(static, url_prefix='/')

The import in the model is this:

from .controller import db

And for the controllers the import is like this:

from flask import Blueprint, render_template, url_for, abort
from ..models import *

Using this setup I can run the application with the command flask run. However (likely due to a configuration error), I cannot use the restarter in that mode, because it shows an error that the python interpreter can't be found.

Hence I thought about using app.run (as you can see in the app.py), which does work in my experience. However, when I start the app with py app.py, I get this error:

Traceback (most recent call last):
  File "app.py", line 2, in <module>
    from .controller import app
ImportError: attempted relative import with no known parent package

I tried adding an __init__.py to the working directory, but that didn't help either.

My question is: How can I use relative imports here without drastically changing the project structure?

History
Why does this post require attention from curators or moderators?
You might want to add some details to your flag.
Why should this post be closed?

0 comment threads

Post
+10
−0

I don't have a py command on my system; for purposes of this answer I assume it's an alias to the python executable.

Running a script from a file is not quite the same as importing it. A script given on the command line doesn't know it's a package (__package__ is not set). That's why relative imports don't work.

What you probably want is to run it by module path, not filename. Assuming your top-level project directory is named yourapp:

python3 -m yourapp.app

Run this from somewhere that yourapp is importable. Unless you've done something odd with PYTHONPATH, the parent of your top-level project directory should work. You can check importability from the current directory with python3 -c 'import yourapp' or similar.

(even better would be to make a setup.py and use it to pip-install the package; then your working directory won't matter. But you specified no structural changes, so.)

History
Why does this post require attention from curators or moderators?
You might want to add some details to your flag.

1 comment thread

General comments (1 comment)
General comments
luap42‭ wrote over 4 years ago

Thanks. That worked. FWIW I don't have to go to the parent directory, but in my test it worked to use python3 -m app (or py, which is a reference to the python executable as you assumed correctly)