Files
workout/routes/endpoints.py
Peter Stockings b875b49eca feat: Refactor endpoint listing into blueprint
- Moved endpoint listing and searching routes (`list_endpoints`, `search_endpoints`) and helper function (`get_routes`) from `app.py` into a new blueprint at `routes/endpoints.py`.
- Added `/endpoints` URL prefix to the blueprint.
- Registered the new `endpoints_bp` blueprint in `app.py`.
- Removed the original endpoint route definitions and helper function from `app.py`.
- Updated `url_for` calls in relevant templates (`endpoints.html`, `base.html`) to reference the new blueprint endpoints (e.g., `endpoints.list_endpoints`).
- Updated `templates/changelog/changelog.html` to document this refactoring.
```
2025-03-31 23:15:24 +11:00

60 lines
2.3 KiB
Python

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)