Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is a Python module import at the bottom ok?

Tags:

python

flask

Pylint is yelling at me for putting a from .views import *at the end of my __init__.pysaying imports should be placed at the top of the module.

If I place it at the top of __init__.py then Flask can't find my routes (views) so that doesn't work. Page doesn't load, 404 error. Loads fine when routes are imported at the end.

A couple questions:

  • Is Pylint wrong to assume that modules should always go at the top and it's acceptable sometimes to import at the end (like in this case)?
  • or is there another way I should be importing my routes?

for reference, in case:

.
├── README.md
├── my_app
│   ├── __init__.py
│   ├── forms.py
│   ├── models.py
│   ├── static
│   ├── templates
│   │   ├── index.html
│   │   └── loggedin.html
│   └── views.py
├── config.py
├── instance
│   └── config.py
├── requirements.txt
└── run.py

example of what's in __init__.py

from flask import Flask, render_template
from authlib.integrations.flask_client import OAuth


app = Flask(__name__, instance_relative_config=True)
app.config.from_object('config')
app.config.from_pyfile('config.py')

oauth = OAuth(app)

APP_CALLBACK_URL = app.config['APP_CALLBACK_URL']
APP_CLIENT_ID = app.config['APP_CLIENT_ID']
APP_CLIENT_SECRET = app.config['APP_CLIENT_SECRET']
APP_DOMAIN = app.config['APP_DOMAIN']
APP_BASE_URL = 'https://' + APP_DOMAIN

my_app = oauth.register(
    'MY_APP',
    client_id=APP_CLIENT_ID,
    client_secret=APP_CLIENT_SECRET,
    api_base_url=APP_BASE_URL,
    access_token_url=APP_BASE_URL + '/oauth/token',
    authorize_url=APP_BASE_URL + '/authorize',
)


from .views import *
like image 786
Kyle Fennell Avatar asked Jan 03 '20 11:01

Kyle Fennell


1 Answers

Generally speaking, imports should go at the top, but Flask documentation talks about this kind of situations and encourages you to do as you did. Taken from https://flask.palletsprojects.com/en/1.1.x/patterns/packages/:

  1. the Flask application object creation has to be in the __init__.py file. That way each module can import it safely and the __name__ variable will resolve to the correct package.

  2. all the view functions (the ones with a route() decorator on top) have to be imported in the __init__.py file. Not the object itself, but the module it is in. Import the view module after the application object is created.

By the way, don't do from .views import *. Do import .views instead.

like image 193
TrilceAC Avatar answered Oct 20 '22 01:10

TrilceAC