Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Python

Flask import issues

Having some issues on a personal project in flask, started a new project and instantly getting an import error, I am needing to maintain the folder structure as is ideally.

app.py

from flask import Flask
from app import views

app = Flask(__name__)

views.py

from app import app

@app.route('/')
def index():
    return "Hello World!"

run.py

from app import app
app.run(debug=True)

Folder structure:

app
    static
    templates
    app.py
    run.py
    views.py

tmp

The error I am getting: Traceback (most recent call last): File "app.py", line 2, in <module> from app import views File "/Users/Josh/PycharmProjects/web1/app/app.py", line 2, in <module> from app import views ImportError: cannot import name 'views'

2 Answers

Jeff Muday
MOD
Jeff Muday
Treehouse Moderator 28,731 Points

I truly like that you recognize that Flask can build out some pretty awesome, big apps! Large parts of NetFlix, Reddit, and AirBnB are built on Flask. So... you can see Flask is up to the heavy lifting!

Your current approach won't quite work because of circular imports and the '@app.route' decorators won't work outside of the app declaration module.

View this as an opportunity to learn newer, cooler Flask techniques-- and truly geek out!

Two things you will want to look into: "app.add_url_rule()" and "Blueprints". Kenneth Love teaches about Blueprints in the Flask Rest API course.

See the code below you might want to adopt for views.py and app.py. The routing and views start taking on a slightly "Djangoesque" quality-- without some of the Django rigidness.

Check out these links for further details:

Organizing Your Project

http://exploreflask.com/en/latest/organizing.html

Modular Applications

https://flask.palletsprojects.com/en/1.0.x/blueprints/

# app.py
from flask import Flask

# simple importing of views module
import views 

app = Flask(__name__)

# below, are your URL rules!
app.add_url_rule('/', 'index', views.index)
app.add_url_rule('/greet/<name>', 'greet', views.greet)
# login route demonstrates the extra options (GET and POST)
app.add_url_rule('/login','login', views.login, methods=['GET','POST'])
# views.py
from flask import request, redirect, url_for

def index():
    return "Hello World!"

def greet(name):
    return "Hey there {}! How are you?".format(name)

def login():
    """login demonstrates GET and POST requests"""
    form = """
    <h1>Login</h1>
    <form method="POST">
    Username:<br>
    <input type="text" name="username"><br>
    Password:<br>
    <input type="password" name="password"><br>
    <input type="submit"><br>
    </form>
    """
    message = ""
    if request.method == 'POST':
        username=request.form.get('username')
        password=request.form.get('password')
        if username=='admin' and password=='secret':
            return redirect(url_for('greet',name=username))
        message = "<p><strong>Incorrect Username and Password</strong></p>"

    return form + message

Thanks for the response Jeff, I will have to have a look at it and finally get round to the restful flask course. Currently just trying to bridge the gap from the more basic flask projects to the more intricate and complicated ones. Don't suppose you have any experience with SQLAlchemy and flask, got an issue I can't crack. I have been on it for a few hours now and stackoverflow seems to be no help.

Every time I run the flask db init I am getting an error: Error: Could not import “app.run”

My structure has changed and files have been added/renamed to conform more with the flask guidelines.

config.py
run.py
app/
    __init__.py
    db_create.py
    models.py
    views.py
    static/
    templates/
        index.html
        layout.html

Code:

run.py

from app import app

app.run(debug=True)

config.py

import os


basedir = os.path.abspath(os.path.dirname(__file__))
SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'app.db')
SQLALCHEMY_TRACK_MODIFICATIONS = True

init.py

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate


app = Flask(__name__)
app.config.from_object('config')
db = SQLAlchemy(app)

migrate = Migrate(app, db)

from app import views, models

db_create.py

from config import SQLALCHEMY_DATABASE_URI
from app import db
import os.path


db.create_all()

models.py

from app import db


class Property(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    address = db.Column(db.String(500), index=True, unique=True)
    start_date = db.Column(db.DateTime)
    duration = db.Column(db.Integer)
    rent = db.Column(db.Float)

views.py

from app import app
from flask import render_template

@app.route('/')
def index():
    return render_template('index.html')
Jeff Muday
MOD
Jeff Muday
Treehouse Moderator 28,731 Points

SQLAlchemy is a great choice for an ORM. PeeWee (written by Charles Leifer) is slightly simpler, but performs as well. Either one will allow connection to a quality database like Postgres, MySQL, or Maria in a production or local file system in a development scenario.

Also, in the app, you may want to use the "g" (global object) to store the database connection and use this in the "@before_request" and "@after_request" methods.

https://flask-ptbr.readthedocs.io/en/latest/tutorial/dbcon.html

There are countless ways to write the run.py file, no one way is best. Here's how I might rewrite it to allow db creation to be triggered from the command like.

$ python run.py --init

import sys
from app import app, db
import config

PORT = 8000 # this could also be set in the config file too
# check for initialization command
if "--init" in sys.argv:
    db.create_all()

# check for port override (Treehouse workspaces supports 3000, 4567, 8000, 8080, 9292)
# usage: python run.py --port 3000
if "--port" in sys.argv:
    PORT =  int(sys.argv[sys.argv.index("--port")+1])

app.run(host='0.0.0.0', port=PORT, debug=False)