def setup_fallback_app(*,
endpoint: str, app=None, websockets: bool = False, path: str = "/",
mode: str = "extend", callback=None,
):
"""
Create an HTTP (and optional WebSocket) fallback to the given endpoint.
This asumes the given endpoint will replicate or provide missing functionality
or the entire service if it can't be provided locally.
"""
# selectors for app types
from bottle import Bottle
# TODO: Implement a mode kwarg that defaults to "extend" and functions like this:
# replace: Replace all paths in the received apps with the proxied endpoint.
# extend: Redirect all paths not already configured to the proxy.
# errors: Catch errors thrown by the app and redirect the failed calls to the proxy.
# trigger: Use a callback function to check. Redirects when result is True.
# Move this explanation to the docstring.
# TODO: We need to use gw.unwrap_all instead and apply the proxy mode to each of the
# apps found there, then we need to return all those apps in a collection.
# collect apps by type
bottle_app = gw.unwrap_one(app, Bottle)
fastapi_app = gw.unwrap_one(app, FastAPI)
prepared = []
# if no matching apps, default to a new Bottle
if not bottle_app and not fastapi_app:
default = Bottle()
prepared.append(_wire_proxy(default, endpoint, websockets, path))
elif bottle_app:
prepared.append(_wire_proxy(bottle_app, endpoint, websockets, path))
elif fastapi_app:
prepared.append(_wire_proxy(fastapi_app, endpoint, websockets, path))
# TODO: Test that this return is properly compatible with web.server.start_app after the fixes
return prepared[0] if len(prepared) == 1 else tuple(prepared)