Skip to content

Commit 0ae5f8d

Browse files
committed
Move app.py to panel folder and add login/logout custom templates and rework docker
1 parent 3cefc7d commit 0ae5f8d

File tree

6 files changed

+224
-13
lines changed

6 files changed

+224
-13
lines changed

Dockerfile

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,10 @@ RUN --mount=type=cache,mode=0777,target=/root/.cache/pip \
1717
pip install -e . && \
1818
mkdir -p /app/src
1919

20+
COPY src /app/src
2021
COPY tests/data /app/tests/data
21-
COPY src/simdec /app/src/simdec
22-
COPY app.py /app/app.py
23-
# matplotlib cache
24-
RUN mkdir -p /app/.config/matplotlib
22+
COPY panel /app/panel
23+
COPY docs/_static /app/_static
2524

2625
# Step 3/3: Image
2726
FROM base as panel
@@ -30,18 +29,24 @@ ENV PYTHONUNBUFFERED True
3029
ENV PYTHONPATH=/app/src
3130
ENV PYTHONIOENCODING=utf-8
3231
ENV ENV=production
33-
ENV PORT=8080
32+
ENV MPLCONFIGDIR=/tmp/matplotlib
33+
EXPOSE 8080
3434

3535
ARG PANEL_TOKEN
36+
ENV PANEL_BASIC_AUTH=$PANEL_TOKEN
3637

3738
COPY --from=builder /usr/local/lib/python3.11/site-packages/ /usr/local/lib/python3.11/site-packages/
3839
COPY --from=builder /usr/local/bin/panel /usr/local/bin/panel
39-
COPY --from=builder /app/src /app/src
40-
COPY --from=builder /app/tests/data /app/tests/data
41-
COPY --from=builder /app/app.py /app/app.py
40+
COPY --from=builder /app /app
4241

43-
WORKDIR /app
4442
RUN useradd app && usermod -a -G app app
4543
USER app
44+
WORKDIR /app
45+
4646
# Run the web service on container startup.
47-
CMD panel serve app.py --address 0.0.0.0 --port $PORT --allow-websocket-origin="*" --basic-auth=$PANEL_TOKEN --num-procs 2 --cookie-secret my_super_safe_cookie_secret
47+
CMD ["panel", "serve", "panel/app.py", \
48+
"--address", "0.0.0.0", "--port", "8080", "--num-procs", "1", "--allow-websocket-origin", "*", \
49+
"--cookie-secret", "panel_cookie_secret", \
50+
"--basic-login-template", "panel/login.html", \
51+
"--logout-template", "panel/logout.html", \
52+
"--static-dirs", "_static=_static"]

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,10 @@ test: ## Run tests with coverage
3939
pytest --cov simdec --cov-report term-missing
4040

4141
serve-dev: ## Serve Panel dashboard - Dev mode
42-
panel serve app.py --show --autoreload
42+
panel serve panel/app.py --show --autoreload
4343

4444
serve: ## Serve Panel dashboard - Prod mode
45-
panel serve app.py
45+
panel serve panel/app.py --basic-auth $(PANEL_TOKEN) --cookie-secret panel_cookie_secret --basic-login-template panel/login.html --logout-template panel/logout.html --static-dirs _static=docs/_static
4646

4747
build-local:
4848
docker build -f ./Dockerfile \

app.py renamed to panel/app.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,8 @@ def tableau_states(res, states):
314314
## Details on inputs' states
315315
"""
316316

317+
logout = pn.widgets.Button(name="Log out")
318+
logout.js_on_click(code="""window.location.href = './logout'""")
317319

318320
pn_params = pn.layout.WidgetBox(
319321
pn.pane.Markdown(top_description, styles={"color": "#0072b5"}),
@@ -326,10 +328,12 @@ def tableau_states(res, states):
326328
pn.pane.Markdown("## Visualization", styles={"color": "#0072b5"}),
327329
switch_histogram_boxplot,
328330
conditional_selector_n_bins,
331+
# pn.Row(logout),
329332
max_width=350,
330333
sizing_mode="stretch_width",
331334
).servable(area="sidebar")
332335

336+
333337
pn_app = pn.Column(
334338
pn.Row(
335339
pn.Column(
@@ -354,5 +358,5 @@ def tableau_states(res, states):
354358
pn.pane.Markdown(states_description, styles={"color": "#0072b5"}),
355359
pn.panel(interactive_tableau_states),
356360
),
357-
)
361+
),
358362
).servable(title="Simulation Decomposition Dashboard")

panel/login.html

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
<!-- Uses the template from https://github.com/holoviz/panel/blob/main/panel/_templates/login.html -->
2+
<!DOCTYPE html>
3+
<html>
4+
<head>
5+
<meta charset="utf-8">
6+
<meta content="width=device-width, initial-scale=1.0" name="viewport">
7+
<meta content="en" name="docsearch:language">
8+
<title>Panel App | Login</title>
9+
<link rel="icon" type="image/x-icon" href="_static/icon.png">
10+
<style>
11+
* {
12+
box-sizing: border-box;
13+
margin:0;
14+
padding: 0;
15+
}
16+
html {
17+
height: 100%;
18+
}
19+
body {
20+
font-family: 'Segoe UI', sans-serif;;
21+
font-size: 1em;
22+
height: 100%;
23+
line-height: 1.6;
24+
}
25+
p {
26+
padding-bottom: 5px;
27+
}
28+
.wrap {
29+
align-items: center;
30+
background: #fafafa;
31+
display: flex;
32+
height: 100%;
33+
justify-content: center;
34+
width: 100%;
35+
}
36+
.login-form {
37+
background: #ffffff;
38+
border: 1px solid #ddd;
39+
margin: 0 auto;
40+
padding: 2em;
41+
width: 350px;
42+
}
43+
.form-input {
44+
background: #fafafa;
45+
border: 1px solid #eeeeee;
46+
padding: 12px;
47+
width: 100%;
48+
}
49+
.form-group {
50+
margin-bottom: 1em;
51+
}
52+
.form-button {
53+
background: #107bba;
54+
border: 1px solid #ddd;
55+
color: #ffffff;
56+
padding: 10px;
57+
text-transform: uppercase;
58+
width: 100%;
59+
}
60+
.form-button:hover {
61+
background: #0072b5;
62+
}
63+
.form-header {
64+
text-align: center;
65+
}
66+
.form-footer {
67+
text-align: center;
68+
}
69+
#logo {
70+
margin-top: 2em;
71+
}
72+
#error-message {
73+
text-align: center;
74+
margin-bottom: 0em;
75+
}
76+
</style>
77+
</head>
78+
<body>
79+
<div class="wrap">
80+
<form class="login-form" action="./login" method="post">
81+
<div class="form-header">
82+
<h3><img id="logo" src="_static/logo.gif" width="150" height="120"></h3>
83+
<br>
84+
<p> Login to access your application</p>
85+
</div>
86+
<div id="error-message" class="form-group">
87+
<p style="color:rgb(255, 0, 0);font-weight:bold" class="errormessage">{{errormessage}}</p>
88+
</div>
89+
<p></p>
90+
<!--Email Input-->
91+
<div class="form-group">
92+
<input name="username" type="text" class="form-input" autocapitalize="off" autocorrect="off" placeholder="username">
93+
</div>
94+
<!--Password Input-->
95+
<div class="form-group">
96+
<input name="password" type="password" class="form-input" placeholder="password">
97+
</div>
98+
<!--Login Button-->
99+
<div class="form-group">
100+
<button class="form-button" type="submit">Login</button>
101+
</div>
102+
<div><small></small></div>
103+
</form>
104+
</div>
105+
</body>
106+
</html>

panel/logout.html

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
<!-- Uses the template from https://github.com/holoviz/panel/blob/main/panel/_templates/logout.html -->
2+
<!DOCTYPE html>
3+
<html>
4+
<head>
5+
<meta charset="utf-8">
6+
<meta content="width=device-width, initial-scale=1.0" name="viewport">
7+
<meta content="en" name="docsearch:language">
8+
<title>Panel App | Logout</title>
9+
<link rel="icon" type="image/x-icon" href="_static/icon.png">
10+
<style>
11+
* {
12+
box-sizing: border-box;
13+
margin:0;
14+
padding: 0;
15+
}
16+
html {
17+
height: 100%;
18+
}
19+
body {
20+
font-family: 'Segoe UI', sans-serif;;
21+
font-size: 1em;
22+
height: 100%;
23+
line-height: 1.6;
24+
}
25+
p {
26+
padding-bottom: 5px;
27+
}
28+
.wrap {
29+
align-items: center;
30+
background: #fafafa;
31+
display: flex;
32+
height: 100%;
33+
justify-content: center;
34+
width: 100%;
35+
}
36+
.login-form {
37+
background: #ffffff;
38+
border: 1px solid #ddd;
39+
margin: 0 auto;
40+
padding: 2em;
41+
width: 350px;
42+
}
43+
.form-input {
44+
background: #fafafa;
45+
border: 1px solid #eeeeee;
46+
padding: 12px;
47+
width: 100%;
48+
}
49+
.form-group {
50+
margin: 1em 0;
51+
}
52+
.form-button {
53+
background: #107bba;
54+
border: 1px solid #ddd;
55+
color: #ffffff;
56+
padding: 10px;
57+
text-transform: uppercase;
58+
width: 100%;
59+
}
60+
.form-button:hover {
61+
background: #0072b5;
62+
}
63+
.form-header {
64+
text-align: center;
65+
}
66+
.form-footer {
67+
text-align: center;
68+
}
69+
#logo {
70+
margin-top: 2em;
71+
}
72+
#error-message {
73+
text-align: center;
74+
margin-bottom: 0em;
75+
}
76+
</style>
77+
</head>
78+
<body>
79+
<div class="wrap">
80+
<form class="login-form" action=".{{ LOGIN_ENDPOINT }}" method="get">
81+
<div class="form-header">
82+
<h3><img id="logo" src="_static/logo.gif" width="150" height="120"></h3>
83+
<br>
84+
<p> Successfully logged out.</p>
85+
</div>
86+
<div class="form-group">
87+
<button class="form-button" type="submit">Login</button>
88+
</div>
89+
<div><small></small></div>
90+
</form>
91+
</div>
92+
</body>
93+
</html>

pyproject.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,13 @@ source = "https://github.com/Simulation-Decomposition/simdec-python"
6868
build.targets.sdist.exclude = [
6969
".github",
7070
"docs",
71+
"panel",
7172
"tests",
7273
"*.rst",
7374
"*.yml",
7475
".*",
76+
"Makefile",
77+
"Dockerfile",
7578
]
7679

7780
[tool.pytest.ini_options]

0 commit comments

Comments
 (0)