from flask import Blueprint, render_template, request, current_app from jinja2_fragments import render_block from flask_htmx import HTMX endpoints_bp = Blueprint('endpoints', __name__, url_prefix='/endpoints') htmx = HTMX() def _get_routes(app): """Helper function to extract routes from the Flask app object.""" routes = [] for rule in app.url_map.iter_rules(): # Exclude static routes and HEAD/OPTIONS methods if rule.endpoint == 'static': continue methods = ', '.join(sorted(rule.methods - {'HEAD', 'OPTIONS'})) route_info = { 'endpoint': rule.endpoint, 'url': rule.rule, 'methods': methods, 'view_func': app.view_functions[rule.endpoint].__name__, 'doc': app.view_functions[rule.endpoint].__doc__ } routes.append(route_info) return routes @endpoints_bp.route('/') def list_endpoints(): """ Lists all API endpoints available in the Flask application. This endpoint retrieves all registered routes, excluding static routes, and displays their details such as endpoint name, URL, allowed HTTP methods, view function name, and a brief description. """ # Pass current_app to the helper function routes = _get_routes(current_app) if htmx: # Assuming 'endpoints.html' uses a block named 'content' return render_block(current_app.jinja_env, 'endpoints.html', 'content', routes=routes) return render_template('endpoints.html', routes=routes) @endpoints_bp.route('/search') def search_endpoints(): """Searches and filters endpoints based on a query.""" # Pass current_app to the helper function routes = _get_routes(current_app) search = request.args.get('search', '').lower() if search: routes = [ route for route in routes if search in route['endpoint'].lower() or search in route['url'].lower() or search in route['methods'].lower() or search in route['view_func'].lower() or (route.get('doc') and search in route['doc'].lower()) # Safer access to 'doc' ] # Renders the partial table return render_template('partials/endpoints_table.html', routes=routes)