Skip to content
Closed
Show file tree
Hide file tree
Changes from 22 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions shiny/_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import copy
import os
import shutil
import secrets
from contextlib import AsyncExitStack, asynccontextmanager
from inspect import signature
Expand Down Expand Up @@ -214,6 +215,18 @@ def __init__(
cast("Tag | TagList", ui), lib_prefix=self.lib_prefix
)

def __del__(self):
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the part distinct to this PR

user_dependencies = [
v.source["subdir"]
for k, v in self._registered_dependencies.items()
if k.startswith("include-")
]

for item in user_dependencies:
if os.path.exists(item):
print("Removing dependency: ", item)
shutil.rmtree(item)

def init_starlette_app(self) -> starlette.applications.Starlette:
routes: list[starlette.routing.BaseRoute] = [
starlette.routing.WebSocketRoute("/websocket/", self._on_connect_cb),
Expand Down
30 changes: 24 additions & 6 deletions shiny/ui/_include_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,37 +214,55 @@ def create_include_dependency(

def maybe_copy_files(path: Path | str, include_files: bool) -> tuple[str, str]:
hash = get_hash(path, include_files)
print("path: ", path, "Hash: ", hash)

# To avoid unnecessary work when the same file is included multiple times,
# use a directory scoped by a hash of the file.
tmpdir = os.path.join(tempfile.gettempdir(), "shiny_include_files", hash)
tmpdir = os.path.join(tempfile.gettempdir(), f"shiny_include_{hash}")
path_dest = os.path.join(tmpdir, os.path.basename(path))
print("tmpdir: ", tmpdir, "path_dest: ", path_dest)

# To avoid unnecessary work when the same file is included multiple times,
# use a directory scoped by a hash of the file.
# Since the hash/tmpdir should represent all the files in the path's directory,
# we can simply return here
# we can check if it exists to determine if we have a cache hit
if os.path.exists(path_dest):
print("Path already exists:", path_dest)
return path_dest, hash

# Otherwise, make sure we have a clean slate
if os.path.exists(tmpdir):
print("Folder already exists, but not files, removing.")
shutil.rmtree(tmpdir)

if include_files:
print(
"Copying all included files from: ",
path,
" with perms: ",
oct(os.stat(path).st_mode),
)
shutil.copytree(os.path.dirname(path), tmpdir)

else:
os.makedirs(tmpdir, exist_ok=True)
print(
"Copying files from: ",
path,
" with perms: ",
oct(os.stat(path).st_mode),
)
shutil.copy(path, path_dest)

return path_dest, hash


def get_hash(path: Path | str, include_files: bool) -> str:
if include_files:
key = get_file_key(path)
else:
dir = os.path.dirname(path)
files = glob.iglob(os.path.join(dir, "**"), recursive=True)
key = "\n".join([get_file_key(x) for x in files])
else:
key = get_file_key(path)

return hash_deterministic(key)


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from pathlib import Path

from shiny import App, Inputs, Outputs, Session, ui

js_file = Path(__file__).parent / "js" / "customjs.js"
css_file = Path(__file__).parent / "css" / "style.css"

# Define the UI
app_ui = ui.page_fluid(
ui.include_css(css_file, method="link_files"),
ui.include_js(js_file, method="link_files"),
ui.h1("Simple Shiny App with External CSS"),
ui.div(
ui.p("This is a simple Shiny app that demonstrates ui.include_css()"),
ui.p("The styling comes from an external CSS file!"),
class_="content",
),
)


# Define the server
def server(input: Inputs, output: Outputs, session: Session):
pass


# Create and run the app
app = App(app_ui, server)
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
body {
background-color: #c8e1f7;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
@import url("./evenmorecss/more.css");

body {
font-family: Arial, sans-serif;
}

h1 {
color: black;
border-bottom: 2px solid #4682b4;
padding-bottom: 10px;
}

.content {
margin: 20px;
padding: 15px;
background-color: white;
border-radius: 5px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}


Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
const newParagraph = document.createElement('p');
newParagraph.textContent = 'Heyo!';
document.body.appendChild(newParagraph);

Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from playwright.sync_api import Page, expect

from shiny.run import ShinyAppProc


def test_inclusion(page: Page, local_app: ShinyAppProc) -> None:
page.goto(local_app.url)

expect(page.locator("body > p")).to_have_text("Heyo!")
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from pathlib import Path

from shiny import App, Inputs, Outputs, Session, ui

js_file = Path(__file__).parent / "customjs.js"
css_file = Path(__file__).parent / "style.css"

# Define the UI
app_ui = ui.page_fluid(
ui.include_css(css_file, method="link"),
ui.include_js(js_file, method="link"),
ui.h1("Simple Shiny App with External CSS"),
ui.div(
ui.p("This is a simple Shiny app that demonstrates ui.include_css()"),
ui.p("The styling comes from an external CSS file!"),
class_="content",
),
)


# Define the server
def server(input: Inputs, output: Outputs, session: Session):
pass


# Create and run the app
app = App(app_ui, server)
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const newParagraph = document.createElement('p');
newParagraph.textContent = 'Heyo!';
document.body.appendChild(newParagraph);
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
body {
background-color: #70bfef;
font-family: Arial, sans-serif;
}

h1 {
color: black;
border-bottom: 2px solid #4682b4;
padding-bottom: 10px;
}

.content {
margin: 20px;
padding: 15px;
background-color: white;
border-radius: 5px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from playwright.sync_api import Page, expect

from shiny.run import ShinyAppProc


def test_inclusion(page: Page, local_app: ShinyAppProc) -> None:
page.goto(local_app.url)

expect(page.locator("body > p")).to_have_text("Heyo!")
Loading