111 lines
3.7 KiB
Python
111 lines
3.7 KiB
Python
import logging
|
|
from importlib.resources import files
|
|
from pathlib import Path
|
|
from typing import Optional, Any
|
|
|
|
import fasthtml.fastapp
|
|
from fasthtml.components import Link, Script
|
|
from starlette.responses import Response
|
|
|
|
from myfasthtml.auth.routes import setup_auth_routes
|
|
from myfasthtml.auth.utils import create_auth_beforeware
|
|
from myfasthtml.core.AuthProxy import AuthProxy
|
|
from myfasthtml.core.instances import RootInstance
|
|
from myfasthtml.core.utils import utils_app
|
|
|
|
logger = logging.getLogger("MyFastHtml")
|
|
|
|
|
|
def get_asset_path(filename):
|
|
"""Get asset file path"""
|
|
return files("myfasthtml") / "assets" / filename
|
|
|
|
|
|
# Get assets directory path
|
|
assets_path = files("myfasthtml") / "assets"
|
|
assets_dir = Path(str(assets_path))
|
|
|
|
|
|
def get_asset_content(filename):
|
|
"""Get asset file content"""
|
|
return get_asset_path(filename).read_text()
|
|
|
|
|
|
def create_app(daisyui: Optional[bool] = True,
|
|
vis: Optional[bool] = True,
|
|
protect_routes: Optional[bool] = True,
|
|
mount_auth_app: Optional[bool] = False,
|
|
base_url: Optional[str] = None,
|
|
**kwargs) -> Any:
|
|
"""
|
|
Creates and configures a FastHtml application with optional support for daisyUI themes and
|
|
authentication routes.
|
|
|
|
:param daisyui: Flag to enable or disable inclusion of daisyUI-related assets for styling.
|
|
Defaults to False.
|
|
:param protect_routes: Flag to enable or disable routes protection based on authentication.
|
|
Defaults to True.
|
|
:param mount_auth_app: Flag to enable or disable mounting of authentication routes.
|
|
Defaults to False.
|
|
:param base_url: Url to use for the application (used by the auth APIs)
|
|
:param kwargs: Arbitrary keyword arguments forwarded to the application initialization logic.
|
|
|
|
:return: A tuple containing the FastHtml application instance and the associated router.
|
|
:rtype: Any
|
|
"""
|
|
hdrs = [
|
|
Link(href="/myfasthtml/myfasthtml.css", rel="stylesheet", type="text/css"),
|
|
Script(src="/myfasthtml/myfasthtml.js"),
|
|
]
|
|
|
|
if daisyui:
|
|
hdrs += [
|
|
Link(href="/myfasthtml/daisyui-5.css", rel="stylesheet", type="text/css"),
|
|
Link(href="/myfasthtml/daisyui-5-themes.css", rel="stylesheet", type="text/css"),
|
|
Script(src="/myfasthtml/tailwindcss-browser@4.js"),
|
|
]
|
|
|
|
if vis:
|
|
hdrs += [
|
|
Script(src="/myfasthtml/vis-network.min.js"),
|
|
]
|
|
|
|
beforeware = create_auth_beforeware() if protect_routes else None
|
|
app, rt = fasthtml.fastapp.fast_app(before=beforeware, hdrs=tuple(hdrs), **kwargs)
|
|
|
|
# remove the global static files routes
|
|
original_routes = app.routes[:]
|
|
app.routes.clear()
|
|
|
|
# Serve assets
|
|
@app.get("/myfasthtml/{filename:path}.{ext:static}")
|
|
def serve_assets(filename: str, ext: str):
|
|
path = filename + "." + ext
|
|
try:
|
|
content = get_asset_content(path)
|
|
|
|
if filename.endswith('.css'):
|
|
return Response(content, media_type="text/css")
|
|
elif filename.endswith('.js'):
|
|
return Response(content, media_type="application/javascript")
|
|
else:
|
|
return Response(content)
|
|
except Exception as e:
|
|
return Response(f"Asset not found: {path}", status_code=404)
|
|
|
|
# and put it back after the myfasthtml static files routes
|
|
for r in original_routes:
|
|
app.routes.append(r)
|
|
|
|
# route the commands and the bindings
|
|
app.mount("/myfasthtml", utils_app)
|
|
|
|
if mount_auth_app:
|
|
# Setup authentication routes
|
|
setup_auth_routes(app, rt, base_url=base_url)
|
|
|
|
# create the AuthProxy instance
|
|
AuthProxy(RootInstance, base_url) # using the auto register mechanism to expose it
|
|
|
|
return app, rt
|