AnswerDotAI / AnswerDotAI/fasthtml

[FEATURE] Support Base URL / Starlette Prefix

Open
#530 2 comments 0 reactions 0 assignees View on GitHub
enhancement
Dominant language
Jupyter Notebook
Stars
7k
Forks
319
Avg merge
28m
Merged PRs (30d)
3

Description

**Is your feature request related to a problem? Please describe.**

I want to run FastHTML application's within my existing web app under a dynamic url prefix. For example: https://apps.aihype.com/username/appname.

**Describe the solution you'd like**

Streamlit let's you configure `--server.baseUrlPath=/username/appname` when starting an app. It will be trickier with FastHTML as both the backend and the frontend need to know about this, but I think it can be done with a settings / environment variable.

**Example code**

I was able to get this mostly working by manually wrapping the app in a custom entrypoint and adding some headers to the generated HTML:

**Wrapper**
```python
os.environ["BASE_PREFIX"] = prefix
if prefix:
print("Prefix detected, wrapping app...")
orig_entrypoint = os.path.basename(entrypoint)
with open("prefixed_app.py", "w") as f:
f.write(f"""from starlette.applications import Starlette
from starlette.routing import Mount
from {orig_entrypoint.replace('.py', '')} import app as orig_app, serve

routes = [Mount("{prefix}", orig_app)]
app = Starlette(routes=routes)

serve(reload=False)""")
```

**App**
```python
headers = (...)
if os.getenv("BASE_PREFIX"):
prefix = os.getenv("BASE_PREFIX")
headers = (
Base(
href=prefix
),
Script(
f"""document.addEventListener('DOMContentLoaded', () => {{
document.body.addEventListener('htmx:configRequest', (event) => {{
event.detail.path = `{prefix}${{event.detail.path}}`
}})
}});
""")
) + headers
... = fast_app("rad.db", hdrs=headers, ...)
```

**Similar implementations**

1. [Streamlit](https://docs.streamlit.io/develop/api-reference/configuration/config.toml) - See `baseUrlPath` in the Server section

**Problem solved**

This would allow users to host multiple apps on a single domain behind an authenticated proxy. It also enables 3rd parties to support hosting fasthtml apps within their existing platforms.

**Additional context**

I imagine my initial approach doesn't catch all cases. For instance I noticed when `live=True` the websocket is not getting re-routed when I mounted the existing Starlette app. The `

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.