Files
MyFastHtml/src/myfasthtml/myfastapp.py
2025-11-26 20:53:12 +01:00

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