Skip to content

refactor server.py for using Blueprint#3033

Open
JanEisermann wants to merge 25 commits intoOpen-MSS:developfrom
JanEisermann:inkludingBP
Open

refactor server.py for using Blueprint#3033
JanEisermann wants to merge 25 commits intoOpen-MSS:developfrom
JanEisermann:inkludingBP

Conversation

@JanEisermann
Copy link
Copy Markdown
Contributor

@JanEisermann JanEisermann commented Mar 13, 2026

Purpose of PR?:

Fixes #2081

Does this PR introduce a breaking change?
included Blueprint, fixed test_load_no_file

If the changes in this PR are manually verified, list down the scenarios covered::
tests succeed, not manually verified

Additional information for reviewer? :
Mention if this PR is part of any design or a continuation of previous PRs

Does this PR results in some Documentation changes?
If yes, include the list of Documentation changes

Checklist:

  • Bug fix. Fixes #
  • New feature (Non-API breaking changes that adds functionality)
  • PR Title follows the convention of <type>: <subject>
  • Commit has unit tests

@JanEisermann JanEisermann changed the title Inkluding bp Inkcuding bp Mar 13, 2026
@JanEisermann JanEisermann changed the title Inkcuding bp Including bp Mar 13, 2026
@JanEisermann JanEisermann changed the title Including bp refactor server.py for using Blueprint Mar 13, 2026
SCRIPT_NAME = os.environ.get('SCRIPT_NAME', '/')

docs_bp = Blueprint(
"docs",
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

# This can be used to set a location by SCRIPT_NAME for testing. e.g. export SCRIPT_NAME=/demo/
SCRIPT_NAME = os.environ.get('SCRIPT_NAME', '/')

docs_bp = Blueprint(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -57,21 +57,24 @@ def file_exists(filepath=None):
DOCS_STATIC_DIR = os.path.join(DOCS_SERVER_PATH, 'static')
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move the section before the first function

logging.warning(message)


def file_exists(filepath=None):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

may be when it is duplicated move it to mslib.utils and import it?

return False


DOCS_SERVER_PATH = os.path.dirname(os.path.abspath(mslib.__file__))
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move the constants to the beginning after the import block, see https://peps.python.org/pep-0008/#constants

@@ -416,7 +416,7 @@ def user_register_handler():
if APP.config['MAIL_ENABLED']:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

have also a look if we have to use current_app instead of the imported APP

# This can be used to set a location by SCRIPT_NAME for testing. e.g. export SCRIPT_NAME=/demo/
SCRIPT_NAME = os.environ.get('SCRIPT_NAME', '/')

DOCS_BP = Blueprint(
Copy link
Copy Markdown
Member

@ReimarBauer ReimarBauer Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could that also be moved to a blueprints/docs?

CHAT_BP = Blueprint('chat', __name__)


@CHAT_BP.route('/undo_changes', methods=["POST"])
Copy link
Copy Markdown
Member

@ReimarBauer ReimarBauer Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this belongs to operation

when the filemanager "fm" is involed this goes to operation

the chatmanager "cm" makes it to chat blueprint



@CHAT_BP.route('/get_all_changes', methods=['GET'])
@verify_user
Copy link
Copy Markdown
Member

@ReimarBauer ReimarBauer Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this belongs to operation


@CHAT_BP.route('/get_change_content', methods=['GET'])
@verify_user
def get_change_content():
Copy link
Copy Markdown
Member

@ReimarBauer ReimarBauer Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this belongs to operation


@CHAT_BP.route('/set_version_name', methods=['POST'])
@verify_user
def set_version_name():
Copy link
Copy Markdown
Member

@ReimarBauer ReimarBauer Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this belongs to operation


@OPERATION_BP.route('/active_users', methods=["GET"])
@verify_user
def active_users():
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this maybe can go with status to an info blueprint?

from mslib.mscolab.app import APP
from mslib.utils import conditional_decorator


Copy link
Copy Markdown
Member

@ReimarBauer ReimarBauer Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The not route related code should be on an other place

check_login, register_user ... verify_user these should be not in the blueprint file
Please look if they can be moved to mslib.utils.auth.py and imported where needed

return wrapper


AUTH_BP = Blueprint('auth', __name__)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

from here that is the part of the blueprint

# This can be used to set a location by SCRIPT_NAME for testing. e.g. export SCRIPT_NAME=/demo/
SCRIPT_NAME = os.environ.get('SCRIPT_NAME', '/')

DOCS_BP = Blueprint(
Copy link
Copy Markdown
Member

@ReimarBauer ReimarBauer Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should become also an own blueprints docs.py

mslib.utils.file_exists
~~~~~~~~~~~~~~~~~
function for app
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

verifies a given filepath is a file

Copy link
Copy Markdown
Member

@ReimarBauer ReimarBauer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's good progress. We can already see it's becoming much more readable. You need to rearrange a few things.

The blueprints should contain as few additional functions as possible.

Especially not ones that need to be imported from other blueprints.

see comments

(url_for('help'), 'Help'),
(url_for('docs.index'), 'Mission Support System',
((url_for('docs.about'), 'About'),
(url_for('docs.install'), 'Install'),
Copy link
Copy Markdown
Member

@ReimarBauer ReimarBauer Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

      (url_for("gallery.plots"), 'Gallery'), is missing

from mslib.utils.get_content import get_content

GALLERY_BP = Blueprint('gallery', __name__, template_folder='templates')

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the gallery feature requests data on /static and the files are on the STATIC_LOCATION

you need to add static_url_path and static_folder


@AUTH_BP.route('/reset_password/<token>', methods=['GET', 'POST'])
def reset_password(token):
try:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reset_password wants to access user/status_password.html
this gives currently jinja2.exceptions.TemplateNotFound: user/status_password.html

fm.modify_user(user, attribute="confirmed_on", value=datetime.datetime.now(tz=datetime.timezone.utc))
fm.modify_user(user, attribute="confirmed", value=True)
return render_template('user/confirmed.html', username=user.username)

Copy link
Copy Markdown
Member

@ReimarBauer ReimarBauer Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

else:
logging.warning("To send emails, the value of MAIL_ENABLED in conf.py should be set to True.")
return render_template('errors/403.html'), 403

this is missing for the developer case


@AUTH_BP.route("/reset_request", methods=['GET', 'POST'])
def reset_request():
if APP.config['MAIL_ENABLED']:
Copy link
Copy Markdown
Member

@ReimarBauer ReimarBauer Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when mail is not enabled it shows

jinja2.exceptions.TemplateNotFound: errors/403.html

when it is enabled it shows

jinja2.exceptions.TemplateNotFound: user/reset_request.html

status_code = 204
token = generate_confirmation_token(email)
confirm_url = url_for('docs.confirm_email', token=token, _external=True)
html = render_template('auth/user/activate.html', username=username, confirm_url=confirm_url)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

auth.confirm_email ?

try:
username = user.username
token = generate_confirmation_token(form.email.data)
reset_password_url = url_for('docs.reset_password', token=token, _external=True)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

auth.reset_password

try:
username = user.username
token = generate_confirmation_token(form.email.data)
reset_password_url = url_for('auth.user.reset_password', token=token, _external=True)
Copy link
Copy Markdown
Member

@ReimarBauer ReimarBauer Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is auth.reset_password it returns an url not a path

if APP.config['MAIL_ENABLED']:
status_code = 204
token = generate_confirmation_token(email)
confirm_url = url_for('auth.user.confirm_email', token=token, _external=True)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is auth.confirm_email it returns an url not a path

{% if uri is defined %}
<p>Click here to
<a href=" {{ url_for(uri.path) }}">{{uri.name}}</a>
<a href=" {{ url_for(docs.uri.path) }}">{{uri.name}}</a>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is likly only uri.path

I get the error message jinja2.exceptions.UndefinedError: 'docs' is undefined

if email is False:
flash("Sorry, your token has expired or is invalid! We will need to resend your authentication email",
'category_info')
return render_template('auth/user/status_password.html', uri={"path": "reset_request", "name": "Resend "
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

auth.reset_request

from mslib.mscolab.conf import setup_saml2_backend
from mslib.mscolab.forms import ResetPasswordForm, ResetRequestForm
from mslib.mscolab.models import User
from mslib.mscolab.app import APP
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

candidata for current_app

import werkzeug
from flask import Blueprint, request, g, jsonify, abort, send_from_directory

from mslib.mscolab.app import APP
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

candidate for current_app

import os
from functools import wraps

from flask import Blueprint, abort, send_from_directory, render_template, url_for, send_file, current_app
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

already current_app :)

in principle we stay on APP when it is initialzation-time code. All others are likly request time based. These should use current_app.

@OPERATION_BP.route('/get_change_content', methods=['GET'])
@verify_user
def get_change_content():
from mslib.mscolab.server import getConfig
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this for ommiting a circular import?


from flask import Blueprint, g, request, jsonify, send_from_directory

from mslib.mscolab.app import APP
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

candidate for current_app

APP.register_blueprint(AUTH_BP)
APP.register_blueprint(CHAT_BP)
APP.register_blueprint(USER_BP)
APP.register_blueprint(OPERATION_BP)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there could be a blank line for separation

from flask_mail import Message
from itsdangerous import URLSafeTimedSerializer, BadSignature

from mslib.mscolab.app import APP
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

candidate for current_app

@@ -33,10 +33,12 @@
from PIL import Image

from mslib.mscolab.app import APP
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

candidate for current_app

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

refactor server.py for using Blueprint

2 participants