Skip to content

Commit

Permalink
upgrade flask (getredash#6138)
Browse files Browse the repository at this point in the history
* upgrade flask

Signed-off-by: Ye Sijun <junnplus@gmail.com>

* fix test

Signed-off-by: Ye Sijun <junnplus@gmail.com>

* override value_proc for click.prompt

Signed-off-by: Ye Sijun <junnplus@gmail.com>

---------

Signed-off-by: Ye Sijun <junnplus@gmail.com>
  • Loading branch information
junnplus authored and emilaineborato committed Jul 24, 2023
1 parent d291627 commit 95920af
Show file tree
Hide file tree
Showing 22 changed files with 147 additions and 122 deletions.
2 changes: 1 addition & 1 deletion redash/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def create_app():
app = Redash()

# Check and update the cached version for use by the client
app.before_first_request(reset_new_version_status)
reset_new_version_status()

security.init_app(app)
request_metrics.init_app(app)
Expand Down
32 changes: 16 additions & 16 deletions redash/authentication/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,16 @@
from datetime import timedelta
from urllib.parse import urlsplit, urlunsplit

from flask import jsonify, redirect, request, url_for, session
from flask import jsonify, redirect, request, session, url_for
from flask_login import LoginManager, login_user, logout_user, user_logged_in
from sqlalchemy.orm.exc import NoResultFound
from werkzeug.exceptions import Unauthorized

from redash import models, settings
from redash.authentication import jwt_auth
from redash.authentication.org_resolving import current_org
from redash.settings.organization import settings as org_settings
from redash.tasks import record_event
from sqlalchemy.orm.exc import NoResultFound
from werkzeug.exceptions import Unauthorized

login_manager = LoginManager()
logger = logging.getLogger("authentication")
Expand Down Expand Up @@ -216,12 +217,9 @@ def log_user_logged_in(app, user):

@login_manager.unauthorized_handler
def redirect_to_login():
if request.is_xhr or "/api/" in request.path:
response = jsonify(
{"message": "Couldn't find resource. Please login and try again."}
)
response.status_code = 404
return response
is_xhr = request.headers.get("X-Requested-With") == "XMLHttpRequest"
if is_xhr or "/api/" in request.path:
return {"message": "Couldn't find resource. Please login and try again."}, 404

login_url = get_login_url(next=request.url, external=False)

Expand All @@ -242,14 +240,11 @@ def logout_and_redirect_to_index():


def init_app(app):
from redash.authentication import (
saml_auth,
remote_user_auth,
ldap_auth,
from redash.authentication import ldap_auth, remote_user_auth, saml_auth
from redash.authentication.google_oauth import (
create_google_oauth_blueprint,
)

from redash.authentication.google_oauth import create_google_oauth_blueprint

login_manager.init_app(app)
login_manager.anonymous_user = models.AnonymousUser
login_manager.REMEMBER_COOKIE_DURATION = settings.REMEMBER_COOKIE_DURATION
Expand All @@ -262,7 +257,12 @@ def extend_session():
from redash.security import csrf

# Authlib's flask oauth client requires a Flask app to initialize
for blueprint in [create_google_oauth_blueprint(app), saml_auth.blueprint, remote_user_auth.blueprint, ldap_auth.blueprint, ]:
for blueprint in [
create_google_oauth_blueprint(app),
saml_auth.blueprint,
remote_user_auth.blueprint,
ldap_auth.blueprint,
]:
csrf.exempt(blueprint)
app.register_blueprint(blueprint)

Expand Down
27 changes: 16 additions & 11 deletions redash/cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,21 @@
from flask.cli import FlaskGroup, run_command, with_appcontext
from rq import Connection

from redash import __version__, create_app, settings, rq_redis_connection
from redash.cli import data_sources, database, groups, organization, queries, users, rq
from redash import __version__, create_app, rq_redis_connection, settings
from redash.cli import (
data_sources,
database,
groups,
organization,
queries,
rq,
users,
)
from redash.monitor import get_status


def create(group):
def create():
app = current_app or create_app()
group.app = app

@app.shell_context_processor
def shell_context():
Expand Down Expand Up @@ -62,25 +69,23 @@ def send_test_mail(email=None):
"""
Send test message to EMAIL (default: the address you defined in MAIL_DEFAULT_SENDER)
"""
from redash import mail
from flask_mail import Message

from redash import mail

if email is None:
email = settings.MAIL_DEFAULT_SENDER

mail.send(
Message(
subject="Test Message from Redash", recipients=[email], body="Test message."
)
)
mail.send(Message(subject="Test Message from Redash", recipients=[email], body="Test message."))


@manager.command("shell")
@with_appcontext
def shell():
import sys
from ptpython import repl

from flask.globals import _app_ctx_stack
from ptpython import repl

app = _app_ctx_stack.top.app

Expand Down
15 changes: 12 additions & 3 deletions redash/cli/data_sources.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from sys import exit

import click
from click.types import convert_type
from flask.cli import AppGroup
from sqlalchemy.orm.exc import NoResultFound

Expand Down Expand Up @@ -40,7 +41,7 @@ def list_command(organization=None):
)


@manager.command()
@manager.command(name="list_types")
def list_types():
print("Enabled Query Runners:")
types = sorted(query_runners.keys())
Expand Down Expand Up @@ -139,11 +140,19 @@ def new(name=None, type=None, options=None, organization="default"):
else:
prompt = "{} (optional)".format(prompt)

_type = types[prop["type"]]

def value_proc(value):
if value == default_value:
return default_value
return convert_type(_type, default_value)(value)

value = click.prompt(
prompt,
default=default_value,
type=types[prop["type"]],
type=_type,
show_default=False,
value_proc=value_proc,
)
if value != default_value:
options_obj[k] = value
Expand All @@ -154,7 +163,7 @@ def new(name=None, type=None, options=None, organization="default"):

if not options.is_valid():
print("Error: invalid configuration.")
exit()
exit(1)

print(
"Creating {} data source ({}) with options:\n{}".format(
Expand Down
4 changes: 2 additions & 2 deletions redash/cli/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def load_extensions(db):
connection.execute(f'CREATE EXTENSION IF NOT EXISTS "{extension}";')


@manager.command()
@manager.command(name="create_tables")
def create_tables():
"""Create the database tables."""
from redash.models import db
Expand All @@ -61,7 +61,7 @@ def create_tables():
stamp()


@manager.command()
@manager.command(name="drop_tables")
def drop_tables():
"""Drop the database tables."""
from redash.models import db
Expand Down
11 changes: 7 additions & 4 deletions redash/cli/groups.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from sys import exit

from sqlalchemy.orm.exc import NoResultFound
from flask.cli import AppGroup
from click import argument, option
from flask.cli import AppGroup
from sqlalchemy.orm.exc import NoResultFound

from redash import models

Expand Down Expand Up @@ -43,7 +43,7 @@ def create(name, permissions=None, organization="default"):
exit(1)


@manager.command()
@manager.command(name="change_permissions")
@argument("group_id")
@option(
"--permissions",
Expand Down Expand Up @@ -119,4 +119,7 @@ def list_command(organization=None):

members = models.Group.members(group.id)
user_names = [m.name for m in members]
print("Users: {}".format(", ".join(user_names)))
if user_names:
print("Users: {}".format(", ".join(user_names)))
else:
print("Users:")
4 changes: 2 additions & 2 deletions redash/cli/organization.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
manager = AppGroup(help="Organization management commands.")


@manager.command()
@manager.command(name="set_google_apps_domains")
@argument("domains")
def set_google_apps_domains(domains):
"""
Expand All @@ -24,7 +24,7 @@ def set_google_apps_domains(domains):
)


@manager.command()
@manager.command(name="show_google_apps_domains")
def show_google_apps_domains():
organization = models.Organization.query.first()
print(
Expand Down
4 changes: 2 additions & 2 deletions redash/cli/queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
manager = AppGroup(help="Queries management commands.")


@manager.command()
@manager.command(name="add_tag")
@argument("query_id")
@argument("tag")
def add_tag(query_id, tag):
Expand All @@ -31,7 +31,7 @@ def add_tag(query_id, tag):
print("Tag added.")


@manager.command()
@manager.command(name="remove_tag")
@argument("query_id")
@argument("tag")
def remove_tag(query_id, tag):
Expand Down
10 changes: 4 additions & 6 deletions redash/cli/users.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

from click import BOOL, argument, option, prompt
from flask.cli import AppGroup
from sqlalchemy.orm.exc import NoResultFound
from sqlalchemy.exc import IntegrityError
from sqlalchemy.orm.exc import NoResultFound

from redash import models
from redash.handlers.users import invite_user
Expand All @@ -26,7 +26,7 @@ def build_groups(org, groups, is_admin):
return groups


@manager.command()
@manager.command(name="grant_admin")
@argument("email")
@option(
"--org",
Expand Down Expand Up @@ -116,7 +116,7 @@ def create(
exit(1)


@manager.command()
@manager.command(name="create_root")
@argument("email")
@argument("name")
@option(
Expand Down Expand Up @@ -155,9 +155,7 @@ def create_root(email, name, google_auth=False, password=None, organization="def
exit(1)

org_slug = organization
org = models.Organization.query.filter(
models.Organization.slug == org_slug
).first()
org = models.Organization.query.filter(models.Organization.slug == org_slug).first()
if org is None:
org = models.Organization(name=org_slug, slug=org_slug, settings={})

Expand Down
12 changes: 6 additions & 6 deletions redash/handlers/base.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import time

from inspect import isclass
from flask import Blueprint, current_app, request

from flask import Blueprint, current_app, request
from flask_login import current_user, login_required
from flask_restful import Resource, abort
from sqlalchemy import cast
from sqlalchemy.dialects import postgresql
from sqlalchemy.orm.exc import NoResultFound
from sqlalchemy_utils.functions import sort_query

from redash import settings
from redash.authentication import current_org
from redash.models import db
from redash.tasks import record_event as record_event_task
from redash.utils import json_dumps
from sqlalchemy.orm.exc import NoResultFound
from sqlalchemy import cast
from sqlalchemy.dialects import postgresql
from sqlalchemy_utils import sort_query

routes = Blueprint(
"redash", __name__, template_folder=settings.fix_assets_path("templates")
Expand Down
7 changes: 4 additions & 3 deletions redash/handlers/static.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from flask import render_template, safe_join, send_file

from flask import render_template, send_file
from flask_login import login_required
from werkzeug.utils import safe_join

from redash import settings
from redash.handlers import routes
from redash.handlers.authentication import base_href
Expand All @@ -13,7 +14,7 @@ def render_index():
response = render_template("multi_org.html", base_href=base_href())
else:
full_path = safe_join(settings.STATIC_ASSETS_PATH, "index.html")
response = send_file(full_path, **dict(cache_timeout=0, conditional=True))
response = send_file(full_path, **dict(max_age=0, conditional=True))

return response

Expand Down
7 changes: 4 additions & 3 deletions redash/models/base.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import functools

from flask_sqlalchemy import BaseQuery, SQLAlchemy
from sqlalchemy.dialects import postgresql
from sqlalchemy.orm import object_session
from sqlalchemy.pool import NullPool
from sqlalchemy_searchable import make_searchable, vectorizer, SearchQueryMixin
from sqlalchemy.dialects import postgresql
from sqlalchemy_searchable import SearchQueryMixin, make_searchable, vectorizer

from redash import settings
from redash.utils import json_dumps
Expand All @@ -15,7 +15,7 @@ def apply_driver_hacks(self, app, info, options):
options.update(json_serializer=json_dumps)
if settings.SQLALCHEMY_ENABLE_POOL_PRE_PING:
options.update(pool_pre_ping=True)
super(RedashSQLAlchemy, self).apply_driver_hacks(app, info, options)
return super(RedashSQLAlchemy, self).apply_driver_hacks(app, info, options)

def apply_pool_defaults(self, app, options):
super(RedashSQLAlchemy, self).apply_pool_defaults(app, options)
Expand All @@ -25,6 +25,7 @@ def apply_pool_defaults(self, app, options):
options["poolclass"] = NullPool
# Remove options NullPool does not support:
options.pop("max_overflow", None)
return options


db = RedashSQLAlchemy(session_options={"expire_on_commit": False})
Expand Down

0 comments on commit 95920af

Please sign in to comment.