Search code examples
pythonflaskpycharm

Flask 404 errors


I am getting 404 errors from a Flask app with Blueprints. This is on Windows 10 running the latest PyCharm and python 3.11.

I have seen several, usualy many years old, version of this question. I have a Flask app that was not complete but was "working" in early development. I was put on a series of other projects and am now back on the Flask app again. I updated python, Flask and its dependencies.

When I launch the app in the PyCharm debugger, it runs and shows me the expected startup info:

FLASK_APP = my_app/my_app.py
FLASK_ENV = development
FLASK_DEBUG = 0
In folder C:/Users/ME/PycharmProjects/Project_folder
import sys; print('Python %s on %s' % (sys.version, sys.platform))
C:\Users\ME\PycharmProjects\Project_folder\venv\Scripts\python.exe C:/JetBrains/PyCharm-2023.2.1/plugins/python/helpers/pydev/pydevd.py --module --multiprocess --qt-support=auto --client 127.0.0.1 --port 50785 --file flask run 
Connected to pydev debugger (build 232.9559.58)
[2023-09-29 14:31:12,134] INFO in my_app: STARTING APP
 * Serving Flask app 'my_app/my_app.py'
 * Debug mode: on
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
 * Running on http://127.0.0.1:5000
Press CTRL+C to quit

My project layout -- edited for brevity

:.
|   my_app.py
|   CONFIG.ini
|   requirements.txt
+---app
|   |   local_settings.py
|   |   settings.py
|   |   __init__.py
|   +---models
|   +---static  
|   +---templates
|   +---views
|   |   |   admin.py
|   |   |   API.py
|   |   |   main.py
|   |   |   utilities.py
|   |   |   __init__.py

I define Blueprints in: admin.py, API.py and main.py. The admin and API sections are only stubs at this moment.

my_app.py looks like:

from app import create_app

my_app = None

try:
    my_app = create_app()
    my_app.logger.info(f'STARTING APP')
except Exception as e:
    msg = repr(e)
    if my_app:
        my_app.logger.error(f'{repr(msg)}')
    print(repr(msg))

aoo/__init__.py looks like the following. Notice the register_blueprints(app) call in create_app(); it comes from app/utilities.py below. It is registering the blueprints because I can put a break point after the function call and see them in the app object along with the rules.

import os
from dotenv import load_dotenv
from flask import Flask
from flask_mail import Mail
from flask_migrate import Migrate
from flask_sqlalchemy import SQLAlchemy
from flask_user import UserManager
from flask_wtf.csrf import CSRFProtect
from app.models.user import User, UserRegisterForm, UserProfileForm, UserLoginForm
from app.views.utilities import register_api, register_blueprints

# Instantiate Flask
app = Flask(__name__)
csrf_protect = CSRFProtect()
mail = Mail()
db = SQLAlchemy()
migrate = Migrate()
user_manager = None

def create_app():
    try:
        load_dotenv()

        app.config.from_object("app.settings")
        app.config.from_object("app.local_settings")

        # Set up an error-logger to send emails to app.config.ADMINS
        init_file_error_handler(app)
        init_email_error_handler(app)

        csrf_protect.init_app(app)
        mail.init_app(app)
        db.init_app(app)
        migrate.init_app(app, db)

        # Setup Flask-User
        global user_manager
        user_manager = UserManager(app, db, User)
        user_manager.RegisterFormClass = UserRegisterForm
        user_manager.EditUserProfileFormClass = UserProfileForm
        user_manager.LoginFormClass = UserLoginForm

        register_blueprints(app)

        return app
    except Exception as e:
        print(repr(e))
        raise e

@app.context_processor
def context_processor():
    return dict(user_manager=user_manager)

def init_file_error_handler(my_app):
    ...

def init_email_error_handler(my_app):
    ...

utilities.py:

from app.views.API import API_blueprint
from app.views.admin import admin_blueprint
from app.views.main import main_blueprint

def register_blueprints(my_app):
    try:
        my_app.register_blueprint(main_blueprint)
        my_app.register_blueprint(admin_blueprint)
        my_app.register_blueprint(API_blueprint)
    except Exception as e:
        raise

def register_api(my_app, view, endpoint, url, pk="id", pk_type="uuid"):
    ...

main.py has the basic home page and other things:

import os
import random
from datetime import timedelta
from flask import redirect, render_template, session
from flask import request, url_for, Blueprint
from flask_user import current_user, login_required

main_blueprint = Blueprint("main", __name__, template_folder="templates")

# The Home page is accessible to anyone
@main_blueprint.route("/")
def home_page():
    from app import app
    ...
    return render_template("main/home_page.html")

The PyCharm debugger starts; I can break on the create_app() call in my_app.py; step over the create step and examine the my_app object and it seems to be correctly populated as far as I know without being an expert on such things.

clicking the URL in the PyCharm debug window brings up a browser but that reports a 404 error. No other errors are thrown as far as I can tell.

Ideas?

Minor edit FLASK_DEBUG should have been set to 0 above.

Update I just learned about the flask routes command. In the debugger I can see that the blueprints have been added but when I run the routs command I get almost nothing:

> flask --app .\my_app\app routes
Endpoint  Methods  Rule                   
--------  -------  -----------------------
static    GET      /static/<path:filename>


Solution

  • So, it is routing again. I am running python 3.11.6, the latest Flask and Flask-Login. I would love to say that I know "the" answer but I stumbled on the fact that Werkzberg has depreciated some of its internals between version 2.3 and 3.0. The depreciated things were removed in 3.0 -- this breaks Flaks-Login. Rolling back Werkzberg to 2.3 seems to have helped. FYI