diff --git a/swh/scheduler/api/server.py b/swh/scheduler/api/server.py --- a/swh/scheduler/api/server.py +++ b/swh/scheduler/api/server.py @@ -33,6 +33,10 @@ return scheduler +def has_no_empty_params(rule): + return len(rule.defaults or ()) >= len(rule.arguments or ()) + + @app.route('/') @negotiate(MsgpackFormatter) @negotiate(JSONFormatter) @@ -159,6 +163,21 @@ return get_sched().delete_archived_tasks(**decode_request(request)) +@app.route("/site-map") +@negotiate(MsgpackFormatter) +@negotiate(JSONFormatter) +def site_map(): + links = [] + sched = get_sched() + for rule in app.url_map.iter_rules(): + if has_no_empty_params(rule) and hasattr(sched, rule.endpoint): + links.append(dict( + rule=rule.rule, + description=getattr(sched, rule.endpoint).__doc__)) + # links is now a list of url, endpoint tuples + return links + + def run_from_webserver(environ, start_response, config_path=DEFAULT_CONFIG_PATH): """Run the WSGI app from the webserver, loading the configuration.""" diff --git a/swh/scheduler/tests/test_api_client.py b/swh/scheduler/tests/test_api_client.py --- a/swh/scheduler/tests/test_api_client.py +++ b/swh/scheduler/tests/test_api_client.py @@ -4,6 +4,7 @@ # See top-level LICENSE file for more information import unittest +import requests from swh.core.tests.server_testing import ServerTestFixture from swh.scheduler import get_scheduler @@ -34,3 +35,19 @@ # accessible through a remote scheduler accessible on the # given port self.backend = get_scheduler('remote', {'url': self.url()}) + + def test_site_map(self): + sitemap = requests.get(self.url() + 'site-map') + assert sitemap.headers['Content-Type'] == 'application/json' + sitemap = sitemap.json() + + rules = set(x['rule'] for x in sitemap) + # we expect at least these rules + expected_rules = set('/'+rule for rule in ( + 'set_status_tasks', 'create_task_type', + 'get_task_type', 'get_task_types', 'create_tasks', 'disable_tasks', + 'get_tasks', 'search_tasks', 'peek_ready_tasks', + 'grab_ready_tasks', 'schedule_task_run', 'mass_schedule_task_runs', + 'start_task_run', 'end_task_run', 'filter_task_to_archive', + 'delete_archived_tasks')) + assert rules.issuperset(expected_rules), expected_rules - rules