improve find_best_app method

This commit is contained in:
ali raza 2023-08-31 07:00:20 +05:00
parent f8db3a841b
commit aa48e09bdf

View file

@ -30,55 +30,46 @@ class NoAppException(click.UsageError):
def find_best_app(module): def find_best_app(module):
"""Given a module instance this tries to find the best possible """Given a module instance, this function tries to find the best possible
application in the module or raises an exception. application in the module or raises an exception.
""" """
from . import Flask
# Search for the most common names first. def find_app_by_attribute(attr_name):
for attr_name in ("app", "application"): return getattr(module, attr_name, None)
app = getattr(module, attr_name, None)
if isinstance(app, Flask): def find_app_by_instance():
return app matches = [v for v in module.__dict__.values() if isinstance(v, Flask)]
return matches[0] if len(matches) == 1 else None
# Otherwise find the only object that is a Flask instance. def find_app_by_factory(attr_name):
matches = [v for v in module.__dict__.values() if isinstance(v, Flask)]
if len(matches) == 1:
return matches[0]
elif len(matches) > 1:
raise NoAppException(
"Detected multiple Flask applications in module"
f" '{module.__name__}'. Use '{module.__name__}:name'"
" to specify the correct one."
)
# Search for app factory functions.
for attr_name in ("create_app", "make_app"):
app_factory = getattr(module, attr_name, None) app_factory = getattr(module, attr_name, None)
if inspect.isfunction(app_factory): if inspect.isfunction(app_factory):
try: try:
app = app_factory() app = app_factory()
return app if isinstance(app, Flask) else None
if isinstance(app, Flask):
return app
except TypeError as e: except TypeError as e:
if not _called_with_wrong_args(app_factory): if not _called_with_wrong_args(app_factory):
raise raise
raise NoAppException( app = None
f"Detected factory '{attr_name}' in module '{module.__name__}',"
" but could not call it without arguments. Use" for attr_name in ("app", "application"):
f" '{module.__name__}:{attr_name}(args)'" app = find_app_by_attribute(attr_name)
" to specify arguments." if isinstance(app, Flask):
) from e return app
app = find_app_by_instance()
if app:
return app
for attr_name in ("create_app", "make_app"):
app = find_app_by_factory(attr_name)
if app:
return app
raise NoAppException( raise NoAppException(
"Failed to find Flask application or factory in module" f"Failed to find Flask application or factory in module '{module.__name__}'."
f" '{module.__name__}'. Use '{module.__name__}:name'" f" Use '{module.__name__}:name' to specify one."
" to specify one."
) )