Skip to content

Commit a53a54b

Browse files
committed
Replace explicit client route registration with SPA catch-all fallback
Galaxy maintained 133 explicit add_client_route() calls in buildapp.py that had to stay in sync with the Vue router -- forget one and the route 404s on page refresh. Since all client routes serve the same static js-app.mako template with no server-side data injection, there's no reason to enumerate them. Instead, when no server route matches a non-API path, the WSGI layer now falls back to serving the SPA directly and lets the Vue router handle routing (including showing its own 404 for truly invalid paths). API paths still 404 normally, static files are handled by URLMap before this code runs, and legacy controller routes still match via the mapper first. This removes the clientside_routes mapper, the add_client_route() method, and all 133 route registrations from buildapp.py.
1 parent 1d45d40 commit a53a54b

File tree

2 files changed

+6
-160
lines changed

2 files changed

+6
-160
lines changed

lib/galaxy/web/framework/base.py

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,6 @@ def __init__(self):
9898
self.controllers = {}
9999
self.api_controllers = {}
100100
self.mapper = routes.Mapper()
101-
self.clientside_routes = routes.Mapper(controller_scan=None, register=False)
102101
# FIXME: The following two options are deprecated and should be
103102
# removed. Consult the Routes documentation.
104103
self.mapper.minimization = True
@@ -132,9 +131,6 @@ def add_route(self, route, **kwargs):
132131
"""
133132
self.mapper.connect(route, **kwargs)
134133

135-
def add_client_route(self, route, controller="root"):
136-
self.clientside_routes.connect(route, controller=controller, action="client")
137-
138134
def set_transaction_factory(self, transaction_factory):
139135
"""
140136
Use the callable `transaction_factory` to create the transaction
@@ -149,7 +145,6 @@ def finalize_config(self):
149145
"""
150146
# Create/compile the regular expressions for route mapping
151147
self.mapper.create_regs(list(self.controllers.keys()))
152-
self.clientside_routes.create_regs()
153148

154149
def trace(self, **fields):
155150
if self.trace_logger:
@@ -212,16 +207,18 @@ def _resolve_map_match(self, map_match, path_info, controllers, use_default=True
212207

213208
def handle_request(self, request_id, path_info, environ, start_response, body_renderer=None):
214209
# Map url using routes
215-
client_match = self.clientside_routes.match(path_info, environ)
216-
map_match = self.mapper.match(path_info, environ) or client_match
210+
map_match = self.mapper.match(path_info, environ)
217211
if path_info.startswith("/api"):
218212
environ["is_api_request"] = True
219213
controllers = self.api_controllers
220214
else:
221215
environ["is_api_request"] = False
222216
controllers = self.controllers
223217
if map_match is None:
224-
raise webob.exc.HTTPNotFound(f"No route for {path_info}")
218+
if environ["is_api_request"]:
219+
raise webob.exc.HTTPNotFound(f"No route for {path_info}")
220+
# Unmatched non-API path: serve the SPA and let the Vue router handle it
221+
map_match = {"controller": "root", "action": "client"}
225222
self.trace(path_info=path_info, map_match=map_match)
226223
# Setup routes
227224
rc = routes.request_config()
@@ -239,20 +236,7 @@ def handle_request(self, request_id, path_info, environ, start_response, body_re
239236
trans.request_id = request_id
240237
rc.redirect = trans.response.send_redirect
241238
# Resolve mapping to controller/method
242-
try:
243-
# We don't use default methods if there's a clientside match for this route.
244-
use_default = client_match is None
245-
controller_name, controller, action, method = self._resolve_map_match(
246-
map_match, path_info, controllers, use_default=use_default
247-
)
248-
except webob.exc.HTTPNotFound:
249-
# Failed, let's check client routes
250-
if not environ["is_api_request"] and client_match is not None:
251-
controller_name, controller, action, method = self._resolve_map_match(
252-
client_match, path_info, controllers
253-
)
254-
else:
255-
raise
239+
controller_name, controller, action, method = self._resolve_map_match(map_match, path_info, controllers)
256240
trans.controller = controller_name
257241
trans.action = action
258242

lib/galaxy/webapps/galaxy/buildapp.py

Lines changed: 0 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -189,144 +189,6 @@ def app_pair(global_conf, load_app_kwds=None, wsgi_preflight=True, **kwargs):
189189
conditions={"method": ["OPTIONS"]},
190190
)
191191

192-
# CLIENTSIDE ROUTES
193-
# The following are routes that are handled completely on the clientside.
194-
# The following routes don't bootstrap any information, simply provide the
195-
# base analysis interface at which point the application takes over.
196-
webapp.add_client_route("/")
197-
webapp.add_client_route("/index")
198-
webapp.add_client_route("/about")
199-
webapp.add_client_route("/admin")
200-
webapp.add_client_route("/admin/data_tables")
201-
webapp.add_client_route("/admin/data_types")
202-
webapp.add_client_route("/admin/jobs")
203-
webapp.add_client_route("/admin/invocations")
204-
webapp.add_client_route("/admin/toolbox_dependencies")
205-
webapp.add_client_route("/admin/data_manager{path_info:.*}")
206-
webapp.add_client_route("/admin/notifications{path_info:.*}")
207-
webapp.add_client_route("/admin/error_stack")
208-
webapp.add_client_route("/admin/users")
209-
webapp.add_client_route("/admin/users/create")
210-
webapp.add_client_route("/admin/display_applications")
211-
webapp.add_client_route("/admin/reset_metadata")
212-
webapp.add_client_route("/admin/roles")
213-
webapp.add_client_route("/admin/forms")
214-
webapp.add_client_route("/admin/notifications")
215-
webapp.add_client_route("/admin/groups")
216-
webapp.add_client_route("/admin/repositories")
217-
webapp.add_client_route("/admin/sanitize_allow")
218-
webapp.add_client_route("/admin/tool_versions")
219-
webapp.add_client_route("/admin/toolshed")
220-
webapp.add_client_route("/admin/quotas")
221-
webapp.add_client_route("/admin/form/{form_id}")
222-
webapp.add_client_route("/admin/api_keys")
223-
webapp.add_client_route("/carbon_emissions_calculations")
224-
webapp.add_client_route("/help/terms/{term_id}")
225-
webapp.add_client_route("/datatypes")
226-
webapp.add_client_route("/login/start")
227-
webapp.add_client_route("/register/start")
228-
webapp.add_client_route("/tools/list")
229-
webapp.add_client_route("/tools/list/ontologies")
230-
webapp.add_client_route("/tools/json")
231-
webapp.add_client_route("/tools/editor")
232-
webapp.add_client_route("/tools/editor/{uuid}")
233-
webapp.add_client_route("/tool_landings/{uuid}")
234-
webapp.add_client_route("/workflow_landings/{uuid}")
235-
webapp.add_client_route("/tours")
236-
webapp.add_client_route("/tours/{tour_id}")
237-
webapp.add_client_route("/chatgxy")
238-
webapp.add_client_route("/chatgxy/{exchange_id}")
239-
webapp.add_client_route("/user")
240-
webapp.add_client_route("/user/notifications{path:.*?}")
241-
webapp.add_client_route("/user/{form_id}")
242-
webapp.add_client_route("/object_store_instances/create")
243-
webapp.add_client_route("/object_store_instances/index")
244-
webapp.add_client_route("/object_store_instances/{user_object_store_id}/edit")
245-
webapp.add_client_route("/object_store_instances/{user_object_store_id}/upgrade")
246-
webapp.add_client_route("/object_store_templates/{template_id}/new")
247-
webapp.add_client_route("/file_source_instances/create")
248-
webapp.add_client_route("/file_source_instances/index")
249-
webapp.add_client_route("/file_source_instances/{user_file_source_id}/edit")
250-
webapp.add_client_route("/file_source_instances/{user_file_source_id}/upgrade")
251-
webapp.add_client_route("/file_source_templates/{template_id}/new")
252-
webapp.add_client_route("/welcome/new")
253-
webapp.add_client_route("/visualizations")
254-
webapp.add_client_route("/visualizations/create/{visualization}")
255-
webapp.add_client_route("/visualizations/display{path:.*?}")
256-
webapp.add_client_route("/visualizations/edit")
257-
webapp.add_client_route("/visualizations/sharing")
258-
webapp.add_client_route("/visualizations/list_published")
259-
webapp.add_client_route("/visualizations/list_shared")
260-
webapp.add_client_route("/visualizations/list")
261-
webapp.add_client_route("/pages/list")
262-
webapp.add_client_route("/pages/list_published")
263-
webapp.add_client_route("/pages/create")
264-
webapp.add_client_route("/pages/edit")
265-
webapp.add_client_route("/pages/editor")
266-
webapp.add_client_route("/pages/sharing")
267-
webapp.add_client_route("/published/history")
268-
webapp.add_client_route("/published/page")
269-
webapp.add_client_route("/published/visualization")
270-
webapp.add_client_route("/published/workflow")
271-
webapp.add_client_route("/histories/citations")
272-
webapp.add_client_route("/histories/list")
273-
webapp.add_client_route("/histories/import")
274-
webapp.add_client_route("/histories/{history_id}/export")
275-
webapp.add_client_route("/histories/{history_id}/archive")
276-
webapp.add_client_route("/histories/{history_id}/invocations")
277-
webapp.add_client_route("/histories/archived")
278-
webapp.add_client_route("/histories/list_published")
279-
webapp.add_client_route("/histories/list_shared")
280-
webapp.add_client_route("/histories/rename")
281-
webapp.add_client_route("/histories/sharing")
282-
webapp.add_client_route("/histories/permissions")
283-
webapp.add_client_route("/histories/view")
284-
webapp.add_client_route("/histories/view_multiple")
285-
webapp.add_client_route("/datasets/copy")
286-
webapp.add_client_route("/datasets/list")
287-
webapp.add_client_route("/datasets/{dataset_id}/edit")
288-
webapp.add_client_route("/datasets/{dataset_id}/error")
289-
webapp.add_client_route("/datasets/{dataset_id}/details")
290-
webapp.add_client_route("/datasets/{dataset_id}/preview")
291-
webapp.add_client_route("/datasets/{dataset_id}/raw")
292-
webapp.add_client_route("/datasets/{dataset_id}/report")
293-
webapp.add_client_route("/datasets/{dataset_id}/show_params")
294-
webapp.add_client_route("/datasets/{dataset_id}/visualize")
295-
webapp.add_client_route("/datasets/{dataset_id}")
296-
webapp.add_client_route("/display_applications/{path:.*?}")
297-
webapp.add_client_route("/collection/{collection_id}/edit")
298-
webapp.add_client_route("/collection/{collection_id}/sheet")
299-
webapp.add_client_route("/collection/new_list")
300-
webapp.add_client_route("/jobs/submission/success")
301-
webapp.add_client_route("/jobs/{job_id}/view")
302-
webapp.add_client_route("/rules")
303-
webapp.add_client_route("/workflows/list")
304-
webapp.add_client_route("/workflows/list_published")
305-
webapp.add_client_route("/workflows/list_shared_with_me")
306-
webapp.add_client_route("/workflows/edit")
307-
webapp.add_client_route("/workflows/export")
308-
webapp.add_client_route("/workflows/create")
309-
webapp.add_client_route("/workflows/rerun")
310-
webapp.add_client_route("/workflows/run")
311-
webapp.add_client_route("/workflows/import")
312-
webapp.add_client_route("/workflows/trs_import")
313-
webapp.add_client_route("/workflows/trs_search")
314-
webapp.add_client_route("/workflows/invocations")
315-
webapp.add_client_route("/workflows/invocations/{invocation_id}")
316-
webapp.add_client_route("/workflows/invocations/{invocation_id}/{tab:.*?}")
317-
webapp.add_client_route("/workflows/invocations/import")
318-
webapp.add_client_route("/workflows/sharing")
319-
webapp.add_client_route("/workflows/{stored_workflow_id}/invocations")
320-
webapp.add_client_route("/workflows/invocations/report")
321-
# webapp.add_client_route('/workflows/invocations/view_bco')
322-
webapp.add_client_route("/custom_builds")
323-
webapp.add_client_route("/interactivetool_entry_points/list")
324-
webapp.add_client_route("/libraries{path:.*?}")
325-
webapp.add_client_route("/storage{path:.*?}")
326-
webapp.add_client_route("/import/zip")
327-
webapp.add_client_route("/downloads")
328-
webapp.add_client_route("/upload{path:.*?}")
329-
330192
# ==== Done
331193
# Indicate that all configuration settings have been provided
332194
webapp.finalize_config()

0 commit comments

Comments
 (0)