Retrieval / comparison of Flask application static content endpoint(s) #4136
-
Hi folks, The With the upgrade to Flask 2.x, issue Frozen-Flask/Frozen-Flask#113 has appeared, and relates to content registered as In some more detail, the cause seems to be a combination of:
Since the lambda function isn't the same method as the Can anyone suggest a fix or improvement to the current equality comparison? (it doesn't seem straightforward for external Python libraries to inspect or compare the contents of a lambda function, so I thought asking in the context of Alternatively, perhaps Thanks! |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 3 replies
-
I've played around with your There's good news! Your approach seems to work fine for Blueprint static folders and additional URL rules that point to send_static_file. To me, this seems to indicate the only thing you need to account for is a built-in static endpoint registered to the TL;DR My Suggested SolutionYou can do this by changing line 439 to if rule.endpoint == 'static' or unwrap_method(view) is send_static_file: Initial Test CodeHere's my test code: from flask import Flask, Blueprint
app = Flask(__name__)
@app.shell_context_processor
def inject():
return {'find_static': _static_rules_endpoints}
# Register a non-static endpoint to make sure it isn't mistakenly
# identified as static
@app.route("/")
def not_static():
return "I am not a static teapot"
# Register an additional static endpoint
app.add_url_rule("/static_2", endpoint="static_2", view_func=Flask.send_static_file)
# Register a blueprint with its own static folder
blue = Blueprint('blueprint', __name__, static_folder='blue_static')
app.register_blueprint(blue)
def unwrap_method(method):
"""Return the function object for the given method object."""
try:
# Python 2
return method.im_func
except AttributeError:
try:
# Python 3
return method.__func__
except AttributeError:
# Not a method.
return method
def _static_rules_endpoints(app):
"""
Yield the 'static' URL rules for the app and all blueprints.
"""
send_static_file = unwrap_method(Flask.send_static_file)
# Assumption about a Flask internal detail:
# Flask and Blueprint inherit the same method.
# This will break loudly if the assumption isn't valid anymore in
# a future version of Flask
assert unwrap_method(Blueprint.send_static_file) is send_static_file
static_rules = []
for rule in app.url_map.iter_rules():
view = app.view_functions[rule.endpoint]
if unwrap_method(view) is send_static_file:
static_rules.append(rule.endpoint)
return static_rules Now if you run
Reasoning Behind SolutionIf you refer to Lines 515 to 520 in 63893a4 you'll see that the name of the endpoint is hardcoded as "static". So adjusting the _static_rules_endpoint loop as follows seems to work:
for rule in app.url_map.iter_rules():
view = app.view_functions[rule.endpoint]
if rule.endpoint == 'static' or unwrap_method(view) is send_static_file:
static_rules.append(rule.endpoint) Now when I run
Caveats
I hope that this helps, or at least gets you thinking about an approach that works for Frozen Flask! |
Beta Was this translation helpful? Give feedback.
I've played around with your
_static_rules_endpoint
function and made some discoveries that will hopefully help.There's good news! Your approach seems to work fine for Blueprint static folders and additional URL rules that point to send_static_file. To me, this seems to indicate the only thing you need to account for is a built-in static endpoint registered to the
static_url_path
on an app object.TL;DR My Suggested Solution
You can do this by changing line 439 to
Initial Test Code
Here's my test code: