Skip to content

Commit

Permalink
fix: embed custom css right away in index.html (#2184)
Browse files Browse the repository at this point in the history
  • Loading branch information
mscolnick authored Aug 30, 2024
1 parent bd58bf9 commit 54a4ebe
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 54 deletions.
1 change: 0 additions & 1 deletion frontend/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@
<marimo-app-config data-config='{{ app_config }}' hidden></marimo-app-config>
<marimo-server-token data-token='{{ server_token }}' hidden></marimo-server-token>
<title>{{ title }}</title>
<link rel="stylesheet" crossorigin href="/custom.css" />
</head>
<body>
<div id="root"></div>
Expand Down
22 changes: 1 addition & 21 deletions marimo/_server/api/endpoints/assets.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import mimetypes
import os
import re
from typing import TYPE_CHECKING, Optional
from typing import TYPE_CHECKING

from starlette.authentication import requires
from starlette.exceptions import HTTPException
Expand All @@ -15,7 +15,6 @@
from marimo._config.manager import UserConfigManager
from marimo._runtime.virtual_file import EMPTY_VIRTUAL_FILE, read_virtual_file
from marimo._server.api.deps import AppState
from marimo._server.file_router import MarimoFileKey
from marimo._server.router import APIRouter
from marimo._server.templates.templates import (
home_page_template,
Expand Down Expand Up @@ -91,25 +90,6 @@ async def index(request: Request) -> HTMLResponse:
return HTMLResponse(html)


# This serves the custom.css file if it was
# supplied in the app config
@router.get("/custom.css")
@requires("read")
def custom_css(request: Request) -> Response:
app_state = AppState(request)
file_key: Optional[MarimoFileKey] = (
app_state.query_params(FILE_QUERY_PARAM_KEY)
or app_state.session_manager.file_router.get_unique_file_key()
)

if not file_key:
return Response("", media_type="text/css")

app_manager = app_state.session_manager.app_manager(file_key)
css = app_manager.read_css_file() or ""
return Response(css, media_type="text/css")


STATIC_FILES = [
r"(favicon\.ico)",
r"(circle-check\.ico)",
Expand Down
10 changes: 9 additions & 1 deletion marimo/_server/templates/templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,14 @@ def notebook_page_template(
"{{ mode }}",
"read" if mode == SessionMode.RUN else "edit",
)
# If has custom css, inline the css and add to the head
if app_config.css_file:
css_contents = read_css_file(app_config.css_file, filename=filename)
if css_contents:
css_contents = f"<style>{css_contents}</style>"
# Append to head
html = html.replace("</head>", f"{css_contents}</head>")

return html


Expand Down Expand Up @@ -167,7 +175,7 @@ def static_notebook_template(
.replace('src="./', f'crossorigin="anonymous" src="{asset_url}/')
)

# Append to body
# Append to head
html = html.replace("</head>", f"{static_block}</head>")
# Append to body
html = html.replace("</body>", f"{code_block}</body>")
Expand Down
7 changes: 7 additions & 0 deletions marimo/_smoke_tests/theming/custom_css.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
# /// script
# requires-python = ">=3.11"
# dependencies = [
# "vega-datasets",
# "marimo",
# ]
# ///
import marimo

__generated_with = "0.8.3"
Expand Down
31 changes: 0 additions & 31 deletions tests/_server/api/endpoints/test_assets.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# Copyright 2024 Marimo. All rights reserved.
from __future__ import annotations

import os
from tempfile import TemporaryDirectory
from typing import TYPE_CHECKING, Any, cast

Expand Down Expand Up @@ -35,36 +34,6 @@ def test_index(client: TestClient) -> None:
assert f"<title>{title}</title>" in content


def test_custom_css_empty(client: TestClient) -> None:
response = client.get("/custom.css", headers=token_header())
assert response.status_code == 200, response.text
assert response.headers["content-type"] == "text/css; charset=utf-8"


def test_custom_css_non_empty(client: TestClient) -> None:
session_manager = AppState.from_app(cast(Any, client.app)).session_manager
css = "/* custom css */"
filename = session_manager.file_router.get_unique_file_key()
assert filename is not None

css_file = os.path.join(os.path.dirname(filename), "custom.css")
with open(css_file, "w") as f:
f.write(css)

# set config
session_manager.app_manager(filename).save_app_config(
{"css_file": "custom.css"}
)

try:
response = client.get("/custom.css", headers=token_header())
assert response.status_code == 200, response.text
assert response.headers["content-type"] == "text/css; charset=utf-8"
assert response.text == css
finally:
os.remove(css_file)


@with_file_router(AppFileRouter.from_files([]))
def test_index_when_empty(client: TestClient) -> None:
# Login page
Expand Down
23 changes: 23 additions & 0 deletions tests/_server/templates/test_templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,29 @@ def test_notebook_page_template_edit_mode(self) -> None:
assert self.filename in result
assert "edit" in result

def test_notebook_page_template_custom_css(self) -> None:
# Create css file
css = "/* custom css */"

css_file = os.path.join(os.path.dirname(self.filename), "custom.css")
with open(css_file, "w") as f:
f.write(css)

try:
result = templates.notebook_page_template(
self.html,
self.base_url,
self.user_config,
self.server_token,
_AppConfig(css_file="custom.css"),
self.filename,
self.mode,
)

assert css in result
finally:
os.remove(css_file)


class TestHomePageTemplate(unittest.TestCase):
def setUp(self) -> None:
Expand Down

0 comments on commit 54a4ebe

Please sign in to comment.