-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Integrate FastHTML replacing FastAPI and React #81
base: master
Are you sure you want to change the base?
Conversation
b7cde84
to
e0c22bf
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here are some initial comments. As the PR is still WIP anyway, I've mostly only looked at the greater ideas, and not too much into the details yet. (Except for the comment about OOB swaps :p )
capella_model_explorer/icons.py
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would make more sense to store all these icons as individual *.svg
files and serve them somewhere below /static
. This allows the browser to cache the files and optimize rendering, since it knows that they must look the same (in the absence of CSS shenanigans, that is). It also makes the licensing situation a bit clearer, as there can be individual license notices attached to each file. Plus, it slightly improves server performance as well, as there's no longer the need to construct several intermediate objects over and over just to show a static image.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought about having .svg
files instead of py components for SVGs.
Do not want to do that because we depend on Tailwind CSS utility classes which will be listed in the class
(respectively FastHTML's cls
) attribute of the <svg>
tags sent to the client instead of attrs of the <svg>
tag itself.
With external .svg
file we would have final values for colors. A solution with string replacements after the reading of SVG files is sth. I do not really want to implement.
We want to be able to configure colors
<svg stroke="black"> <!-- light theme -->
<svg stroke="white"> <!-- dark theme -->
Example pseudo-code of current implementation:
constants.py
STROKE_ACCENT: t.Final[dict[str, str]] = {
"dark": "white",
"light": "black"
}
icons.py
from fasthtml import svg
import constants as c
THEME: str = "dark"
def icon() -> t.Any:
return fh.Svg(
svg.Path(...),
cls=f"stroke-{c.STROKE_ACCENT[THEME]}""
)
I am open for discussion. It has for sure benefits when dealing with .svg
files which can easily be edited/ downloaded etc..
ft.Div(model_element["uuid"], cls="text-xs text-sky-700") | ||
if state.show_uuids | ||
else None, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the future, we'll probably want to make this a client- (or session-) specific setting that's configurable via some settings UI.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
see #102
8e79d21
to
2391551
Compare
6d7bbb9
to
0134fe1
Compare
Please add a way to disable that. uvicorn's live reloading feature injects a websocket connection that reloads the page automatically. Problem with that is that it also tries to reload the page when that websocket connection breaks, for example due to the server going down. This reload then of course fails, because the server is down now, and just shows an error page. So the effect is that you can't just keep an old version of a page opened in the background. I want to be able to do just that, for example to compare against a newer template version, or just to look at the current DOM and make template changes without constantly being thrown around in the page inspector due to the reloads. Also, the feature should be disabled when deploying the docker image to e.g. the Collab Manager, where the templates are immutable anyway. |
6b86c3c
to
cdd0938
Compare
cdd0938
to
d4c4c78
Compare
f46b53b
to
8c8f1a5
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Haven't looked at much of the actual code yet. More important stuff came up, so I don't know when I'll be able to. So here you go.
pyproject.toml
Outdated
"Programming Language :: Python :: 3.11", | ||
"Programming Language :: Python :: 3.12", | ||
"Programming Language :: Python :: 3.13", | ||
"Development Status :: 1 - Planning", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did you also change the indentation width of this entire file? We're using 2 spaces in Jinja as well, so it's not like everything else is 4 spaces anyway. This just seems unnecessary to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mysterious effect. fixed that. will appear with next push.
static/README.md
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we need a README for /static
in a web app 🙃
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
idea was to document how the .ico
can be made. forgot to push the locally got ignored dev
subfolder.
after we checked that chrome understands to display .svg
favicons directl too, i remove this anyway.
capella_model_explorer/__main__.py
Outdated
subprocess.run( | ||
cmd, | ||
check=True, | ||
capture_output=False, | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
subprocess.run( | |
cmd, | |
check=True, | |
capture_output=False, | |
) | |
subprocess.check_call(cmd) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thx. done.
) | ||
|
||
|
||
def run_local(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cme run local
needs to build the CSS if it doesn't exist already (for example after a fresh clone).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice one. thx!
] | ||
) | ||
cmd.append("capella_model_explorer.main:app") | ||
print(" ".join(cmd)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left-over debug print.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not really, do this after all of the cmd runs. want to leave that including the non-dev case run local
.
may help to get this line from anybody, if sth went wrong...
capella_model_explorer/__main__.py
Outdated
thread = threading.Thread(target=build_css, kwargs={"watch": True}) | ||
thread.start() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't need to be a thread. We can simply do the launch preparation serially, then start the two processes with Popen()
, and await both of them using:
with uvicorn, tailwindcli:
time.sleep(float("inf"))
capella_model_explorer/__main__.py
Outdated
if not pathlib.Path(c.TEMPLATES_DIR).is_dir(): | ||
raise SystemExit(f"Templates directory '{c.TEMPLATES_DIR}' not found.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if not pathlib.Path(c.TEMPLATES_DIR).is_dir(): | |
raise SystemExit(f"Templates directory '{c.TEMPLATES_DIR}' not found.") | |
if not pathlib.Path(c.TEMPLATES_DIR).is_dir(): | |
raise SystemExit(f"Templates directory not found: {c.TEMPLATES_DIR}") |
1e69029
to
2173540
Compare
One can set cme run local -h |
# }}} | ||
|
||
# install Nodep kgs and build the CSS {{{ | ||
RUN npm clean-install && uv run python3 -m capella_model_explorer build css |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't even need a multi-stage build, we can just remove the node_modules
right here. They're not needed after this step anymore, as far as I can tell.
RUN npm clean-install && uv run python3 -m capella_model_explorer build css | |
RUN npm clean-install && uv run python3 -m capella_model_explorer build css && rm -rf node_modules |
5b3b2ea
to
2e36557
Compare
This introduces a major change by replacing the FastAPI backend and React frontend with FastHTML. The integration involves reusing existing code where possible, but also includes significant rewrites that affect the application's behavior. This update aims to enhance performance and streamline the development process. This commit also introduces project management tool which replaces the Makefile with a Python CLI tool. The tool manages the project, including building the Docker image, running the app in a container, and running the app locally. The tool also builds the Tailwind CSS stylesheet. The app always runs with hot template reloading enabled. In development mode, it also runs with hot code reloading. After cloning the project, one can get further information by running: ```bash cme -h cme run -h cme build -h ``` Co-authored-by: Martin Lehmann <[email protected]>
2e36557
to
d7de46a
Compare
This introduces several major changes by
The project can be managed including
New is also a hot template reloading, which is enabled per default.
In development mode, it also runs with hot code reloading.
The FastHTML integration involves reusing existing code where possible, but also includes significant rewrites that affect the application's behavior. This update aims to enhance performance and streamline the development process.
Open issues/ topics
ROUTE_PREFIX
work for static filesdocker
must set tool versions via three--build-arg
specsdiagramViewer.js
work (scaling must be fixed for diagrams with a height which is greater than the width)README.md
/CONTRIBUTING.md
!
) that this PR introduces breaking changes.Integration in Capella Collaboration Manager
MODEL_ENTRYPOINT
-->CME_MODEL
andROUTE_PREFIX
-->CME_ROUTE_PREFIX
Align this with main contributor @MoritzWeber0 of https://github.com/DSD-DBS/capella-collab-manager.gitCME_LIVE_MODE=0
in the tool config