I followed along with a youtube tutorial learning how to create a Flask website, and it works perfectly on my local machine.
I created a subdomain in my cPanel and used the 'setup Python app' wizard to create the app, it worked. So I uploaded the Flask app I made to the server and installed all the requirements. went to the site and this is what I get:
Website
The home page is displayed (it shouldn't be, it should direct you to the login page) and it seems to be overlapping with the navbar. all the links in the navbar return a 500 error, with no log in the error reports on the cPanel.
I've been trying to get it to work for 3 days I can't get it to work.
File tree:
File Tree
The Website folder holds all the files and templates
run.py:
from Website import create_app
app = create_app()
if __name__ == '__main__':
app.run()
passenger_wsgi.py:
import imp
import os
import sys
sys.path.insert(0, os.path.dirname(__file__))
wsgi = imp.load_source('wsgi', 'run.py')
application = wsgi.app
Website.init.py:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_bcrypt import Bcrypt
from flask_login import LoginManager
from flask_mail import Mail
from Website.config import Config
db = SQLAlchemy()
bcrypt = Bcrypt()
login_manager = LoginManager()
login_manager.login_view = 'users.login'
login_manager.login_message_category = 'info'
mail = Mail()
def create_app(config_class=Config):
app = Flask(__name__)
app.config.from_object(Config)
db.init_app(app)
bcrypt.init_app(app)
login_manager.init_app(app)
mail.init_app(app)
from Website.users.routes import users
from Website.posts.routes import posts
from Website.main.routes import main
from Website.errors.handlers import errors
from Website.booking.routes import booking
app.register_blueprint(users)
app.register_blueprint(posts)
app.register_blueprint(main)
app.register_blueprint(errors)
app.register_blueprint(booking)
return app
Can anyone please help figure out what I've done wrong?
Problem seems to be with URL_for() command to route links
The home page is displayed (it shouldn't be, it should direct you to the login page) <
Could be because you need to add the login decorator to the route for the home page url. could also be because you're already logged in (you logged in to upload the files to your cpanel/hosting server and haven't yet logged out; you should try opening your app in a different browser or private window in same browser)
it seems to be overlapping with the navbar. <
This is usually due to path issues i.e. your app is not seeing the correct path for your static files (any stylesheets, images, etc). To confirm, copy the full url to your stylesheet and try to open it in a new browser tab. If you get a 404, that tells you your path is incorrect
Answering my own question.
The problem was with the url_for() command to route the pages together. Not sure what the problem was but it wasn't looking in the right place. I fixed it by going to the .htaccess file and adding
RewriteEngine On
RewriteRule ^http://%{HTTP_HOST}%{REQUEST_URI} [END,NE]
no more 500 errors and it could find the css file.
Related
I've been trying to deploy my Flask app to Heroku for over a day, watching/reading several tutorials, and digging through all the stackoverflow questions i could find and still haven't found a solution for my issue. When i deploy my app, I get the error "gunicorn.errors.AppImportError: Failed to find attribute 'app' in 'app'." I've changed my Procfile many times to get heroku to run my app but i always get the same error.
This is how my app is structured:
enter image description here
My Procfile includes this statement:
web: gunicorn app:app --preload
I am thinking my issues could be how im creating my app, but could not find a solution. My main app file looks like this:
from venv import create
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from os.path import join, dirname, realpath
from flask_login import LoginManager
db = SQLAlchemy()
def create_app():
app = Flask(__name__, static_folder='static')
app.debug = True
app.config['SECRET_KEY'] = 'abcde12568901fghij'
#app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///db.sqlite3'
app.config['SQLALCHEMY_DATABASE_URI'] = '[removed for privacy]'
app.config['UPLOAD_DIRECTORY'] = join(dirname(realpath(__file__)), 'uploads/')
app.config['MAX_CONTENT_LENGTH'] = 16*1024*1024 #16mb
app.config['ALLOWED_EXTENSIONS'] = ['.jpg','.jpeg','.png','.gif','.mp4']
db.init_app(app)
login_manager = LoginManager()
login_manager.login_view = 'auth.login'
login_manager.init_app(app)
from models import User
#login_manager.user_loader
def load_user(user_id):
# since the user_id is just the primary key of our user table, use it in the query for the user
return User.query.get(int(user_id))
from auth import auth
app.register_blueprint(auth)
from views import main
app.register_blueprint(main)
return app
if __name__ == '__main__':
db.create_all(app=create_app())
Screenshot of full logs:
enter image description here
Any help would be greatly appreciated, thanks all!
app:app tells Gunicorn to look for a variable called app in your app.py file (strictly speaking, in your app module), but you don't have a variable with that name.
Instead, you have a function create_app() that returns your app object. Gunicorn allows you to use that directly:
The variable name can also be a function call. In that case the name will be imported from the module, then called to get the application object. This is commonly referred to as the "application factory" pattern.
Update your Procfile accordingly:
web: gunicorn 'app:create_app()' --preload
Do you have another file in your root directory that is creating the app or is the code above the file that you run to run the app? This will normally just be a Python file with the name of your project, and this will have something like app = create_app().
Then your Procfile needs to look for the app in that file.
For example if that file was called mainApp.py you would then use
web: gunicorn mainApp:app --preload
I'm working on a Flask project which include sending confirmation email links. However, by using flask-restful, there is a problem of circular importing modules.
In my app.py file, I've imported modules and use api.add_resource
# app.py file
from flask_restful import Api
from flask import Flask
from account import Register
from flask_mail import Mail
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = ''
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config.from_pyfile('core/config.py')
mail = Mail(app)
api = Api(app)
api.add_resource(Register, '/register')
if __name__ == '__main__':
app.run(debug=True)
And in my account.py file, I need to send an email for each POST request like this
from app import mail
class Register(Resource):
# init some msg and configuration
mail.send(msg)
Now this is a circular import, since app.py import account.py and account.py import app.py to use mail. Can anyone have any solution for this problem without abandon using flask-restful module?
Most simple and direct answer will be: import module, not symbol from module.
So, instead of from account import Register do import account and then api.add_resource(account.Register, '/register').
Similar approach for account.py should work as well:
import app
class Register(Resource):
app.mail.send(msg)
Some basic explanations can be found at https://github.com/Khan/style-guides/blob/master/style/python.md#imports
I'm trying to test my database how it behaves in a many-to-many relationships. I'm struggling to access the application context of the Flask app.
I ran the Python terminal in the parent folder of the app and followed the steps found on SO and elsewhere. I could manage (i think) to import the app, create it, push the context, import the db. However, whenever I want to import models I'm prompted with a:
Error ModuleNotFoundError: No module named 'db'
Despite the fact that db is definately defined:
This is the screenshot of the complete process.
The folder structure is:
- app
--__int__.py
This is the app/init.py file:
from flask import Flask,Blueprint
from flask_sqlalchemy import SQLAlchemy
from app.config import Config
from mailjet_rest import Client
db = SQLAlchemy()
mailjet = Client(auth=(Config.MJ_APIKEY_PUBLIC, Config.MJ_APIKEY_PRIVATE), version='v3.1')
def create_app(config_class=Config):
app = Flask(__name__)
app.config.from_object(Config)
db.init_app(app)
from app.views.users import users
from app.views.data import data
from app.views.admin import admin
app.register_blueprint(users,url_prefix='/users')
app.register_blueprint(data,url_prefix='/data')
app.register_blueprint(admin,url_prefix='/admin')
# with app.app_context():
# db.create_all()
return app
I'd greatly appreciate any input!
Thank you,
Matija
The solution was quite simple. I ought to import models from app.models and not from db.
The steps I took:
Rename the folder to app
Ran Flask shell command on the app level
Imported app
Import models from app.models
I have an extremely large application that is factored into many blueprints. I need to configure the entire application to save files into a directory when a user uploads files. So I am setting ["SESSION_FILE_DIR"] = 'C:/some/path' to the path where files would live after upload in the app.py file.
The documentation reads that configuration settings are shared across the blueprints. I'm experiencing one issue that is not working and below is a stripped down example to replicate my problem to support my question. So, to debug I've created an extremely simple version just printing the path to screen to see what is happening.
If I head over to the URL .../print_dir then the ["SESSION_FILE_DIR"] = 'C:/some/path' is printed to screen. However, if I head over to the URL defined within the blueprint .../new then I am given an error of NameError: name 'server' is not defined.
How can I configure my app such that the same ["SESSION_FILE_DIR"] can be used across blueprints?
The contents of my main app.py are as follows:
from flask import Flask, render_template, request, session
from flask_session import Session
import tempfile
server = Flask(__name__)
server.config["SESSION_PERMANENT"] = False
server.config["SESSION_TYPE"] = "filesystem"
server.config["SESSION_FILE_DIR"] = 'C:/some/path'
server.secret_key = 'abcdefg'
### Import and Register Blueprints
from tools.routes import my_bp
server.register_blueprint(my_bp)
#server.route('/')
def homepage():
return "Hello"
#server.route('/print_dir')
def homepage2():
return server.config["SESSION_FILE_DIR"]
if __name__ == '__main__':
server.run(debug=True)
and now suppose the blueprint lives in a subdirectory called tools and contains the following:
from flask import Flask, render_template, request, session, Blueprint
from flask_session import Session
my_bp = Blueprint("my_bp", __name__)
#my_bp.route('/new', methods=['POST', 'GET'])
def path():
path = server.config["SESSION_FILE_DIR"]
return path
To access the app.config from within a Blueprint, you can import current_app from flask.
Example:
# ./app.py
from flask import Flask
from views.blueprint import bp
app = Flask(__name__)
# Set the config you want:
app.config['IMPORTANT_DIRECTORY'] = '~/path/to/important/directory'
# Register your blueprint
app.register_blueprint(bp)
# ./views/blueprint.py
from flask import Blueprint, current_app
bp = Blueprint('bp', __name__)
#bp.route('/path')
def get_path():
# access the config
path = current_app.config['IMPORTANT_DIRECTORY']
return path
You can find more info in the api docs for flask.
I am using AWS cloud9 IDE and Python flask to develop a webpage where users can create an account and sign in. However when I run my program I get from flasklab8 import app
File "/home/ec2-user/environment/flasklab8/flasklab8/app/init.py", line 15, in
from flasklab8 import routes
ImportError: cannot import name 'routes'. There are a few other files for this web page but I think this is the only file that is causing the issue if needed I can edit in the rest of the code. I also do not know if this is because I am using AWS. The code for the problem file is below:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_bcrypt import Bcrypt
from flask_login import LoginManager
app = Flask(__name__)
app.config['SECRET_KEY'] = '5791628bb0b13ce0c676dfde280ba245'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db'
db = SQLAlchemy(app)
bcrypt = Bcrypt(app)
login_manager = LoginManager(app)
login_manager.login_view = 'login'
login_manager.login_message_category = 'info'
from flasklab8 import routes
It looks like your file chain is
/home/ec2-user/environment/flasklab8/flasklab8/app/init.py
Unless you are doing something really strange, you routes.py file should be in your app folder, not your flasklab8, meaning your import statement is incorrect. It should read
from app import routes