Skip to content

Commit 432016b

Browse files
authored
Dash into the future
Dash into the future
2 parents 9a82675 + 966c152 commit 432016b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+1244
-682
lines changed

Dockerfile.dash

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@ FROM python:3.7.7-slim-buster
22

33
WORKDIR /code
44

5+
ARG PORT
6+
ENV PORT $PORT
7+
58
COPY requirements.txt requirements.txt
6-
RUN pip install -q -r requirements.txt
9+
RUN pip install -r requirements.txt
710

811
COPY src src
912

docker-compose-dash.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
version: '3.1'
2+
3+
services:
4+
app:
5+
build:
6+
context: .
7+
dockerfile: Dockerfile.dash
8+
args:
9+
- PORT=${PORT}
10+
restart: always
11+
ports:
12+
- "${PORT}:8000"

script/server-dash

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#!/usr/bin/env bash
2+
3+
# script/server: Launch the application and any extra required processes
4+
# locally.
5+
6+
set -e
7+
cd "$(dirname "$0")/.."
8+
9+
10+
script/bootstrap
11+
12+
if [ ! -f ".env" ]; then
13+
echo
14+
echo "==> Initializing .env…"
15+
cp .env.example .env
16+
fi
17+
18+
echo
19+
echo "==> Loading .env…"
20+
set -o allexport; source .env; set +o allexport
21+
22+
echo
23+
echo "==> Starting containers with docker-compose…"
24+
docker-compose -f docker-compose-dash.yml up -d --build
25+
26+
echo
27+
echo "==> App is now ready to go!"
28+
echo " *Open http://localhost:${PORT}"
29+
echo

setup.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@
3030
"dash",
3131
"dash_bootstrap_components",
3232
"pyyaml",
33-
"gunicorn"
33+
"gunicorn",
34+
"selenium"
3435
],
3536
classifiers=[
3637
"Programming Language :: Python :: 3",
@@ -44,3 +45,4 @@
4445
keywords=[],
4546
include_package_data=True,
4647
)
48+

src/__init__.py

Whitespace-only changes.

src/assets/favicon.ico

-822 Bytes
Binary file not shown.

src/chime_dash/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
This directory provides the interface for the dash app.
44

5-
![Current interface](docs/assets/interface.png)
5+
![Current interface](docs/interface.png)
66

77
## Tree
88
Structure of the app

src/chime_dash/__init__.py

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,50 @@
1-
x = 1
1+
"""
2+
chime_dash/app
3+
4+
dash instance defined here
5+
"""
6+
7+
from dash import Dash
8+
from typing import TypeVar
9+
from chime_dash.app.config import from_object
10+
from penn_chime.settings import get_defaults
11+
from chime_dash.app.components import Body
12+
from chime_dash.app.utils.callbacks import wrap_callbacks
13+
14+
DashAppInstance = TypeVar('DashAppInstance')
15+
DEFAULTS = get_defaults()
16+
17+
def create_app(context:str='prod')-> DashAppInstance:
18+
"""
19+
create_app initializes the app instance
20+
21+
Args:
22+
context (str, optional): One of either 'prod', 'dev', 'testing.
23+
Defaults to 'prod' where dash.Dash.run_server(debug=False).
24+
Change to 'dev' or 'test' to set debug to true.
25+
26+
Returns:
27+
Env: Config variables based on context argument received
28+
DashAppInstance: Dash instance with appropriate configuration settings
29+
"""
30+
31+
Env = from_object(context)
32+
33+
LANGUAGE = Env.LANG
34+
body = Body(LANGUAGE, DEFAULTS)
35+
36+
37+
App = Dash(
38+
__name__,
39+
external_stylesheets=body.external_stylesheets,
40+
external_scripts=body.external_scripts,
41+
)
42+
43+
App.title = Env.CHIME_TITLE
44+
App.layout = body.html
45+
wrap_callbacks(App)
46+
47+
48+
49+
return Env, App
50+

src/chime_dash/app/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
"""/app
2+
where the magic happens
3+
"""

src/chime_dash/app/components/__init__.py

Lines changed: 39 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -9,101 +9,71 @@
99
"""
1010
from collections import OrderedDict
1111

12-
from dash_bootstrap_components import Row, Col
12+
from dash_bootstrap_components import Container, Row
1313
from dash_bootstrap_components.themes import BOOTSTRAP
14-
from dash_html_components import Script, Div
14+
from dash_html_components import Div
1515

16-
from penn_chime.defaults import Constants
17-
from penn_chime.models import SimSirModel
16+
from chime_dash.app.components.base import Component
17+
from chime_dash.app.components.navbar import Navbar
18+
from chime_dash.app.pages.index import Index
19+
from chime_dash.app.pages.sidebar import Sidebar
1820

1921

20-
from chime_dash.app.components.base import Component, HTMLComponentError
21-
from chime_dash.app.components.sidebar import Sidebar
22-
from chime_dash.app.components.header import Header
23-
from chime_dash.app.components.intro import Intro, ToolDetails
24-
from chime_dash.app.components.additions import Additions
25-
from chime_dash.app.components.visualizations import Visualizations
26-
from chime_dash.app.components.definitions import Definitions
27-
from chime_dash.app.components.footer import Footer
28-
from chime_dash.app.components.navbar import Navbar
22+
def singleton(class_):
23+
instances = {}
24+
25+
def get_instance(*args, **kwargs):
26+
if class_ not in instances:
27+
instances[class_] = class_(*args, **kwargs)
28+
return instances[class_]
29+
return get_instance
2930

3031

32+
@singleton
3133
class Body(Component):
3234
"""
3335
"""
34-
3536
external_stylesheets = [
36-
"https://www1.pennmedicine.org/styles/shared/penn-medicine-header.css",
3737
BOOTSTRAP,
38+
'https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,400;0,600;1,400;1,600&display=swap',
3839
]
3940

4041
def __init__(self, language, defaults):
4142
"""
4243
"""
4344
super().__init__(language, defaults)
4445
self.components = OrderedDict(
45-
sidebar=Sidebar(language, defaults),
46-
header=Header(language, defaults),
47-
intro=Intro(language, defaults),
48-
tool_details=ToolDetails(language, defaults),
49-
visualizations=Visualizations(language, defaults),
50-
additions=Additions(language, defaults),
51-
definitions=Definitions(language, defaults),
52-
footer=Footer(language, defaults),
5346
navbar=Navbar(language, defaults),
47+
sidebar=Sidebar(language, defaults),
48+
# todo subscribe to changes to URL and select page appropriately
49+
index=Index(language, defaults),
5450
)
55-
self.callback_outputs = []
56-
self.callback_inputs = OrderedDict()
57-
self.callback_keys = []
58-
for component in self.components.values():
59-
self.callback_outputs += component.callback_outputs
60-
self.callback_inputs.update(component.callback_inputs)
6151

6252
def get_html(self):
6353
"""Glues individual setup components together
6454
"""
6555
return Div(
66-
children=self.components["navbar"].html
67-
+ [
68-
Row(
69-
children=[
70-
Col(
71-
id="sidebar",
72-
children=self.components["sidebar"].html,
73-
width=3,
74-
className="mt-4",
75-
),
76-
Col(width=1),
77-
Col(
78-
self.components["header"].html
79-
+ self.components["intro"].html
80-
+ self.components["tool_details"].html
81-
+ self.components["visualizations"].html
82-
+ self.components["additions"].html
83-
+ self.components["definitions"].html
84-
+ self.components["footer"].html,
85-
width=8,
86-
className="mt-4",
87-
),
88-
],
89-
className="container",
90-
),
56+
className="app",
57+
children=self.components["navbar"].html + [
58+
Div(
59+
className="app-content",
60+
children=
61+
self.components["sidebar"].html
62+
+ self.components["index"].html
63+
)
9164
]
9265
)
9366

94-
def callback(self, *args, **kwargs):
95-
"""
67+
def get_html_old(self):
68+
"""Glues individual setup components together
9669
"""
97-
kwargs = dict(zip(self.callback_inputs, args))
98-
pars = self.components["sidebar"].parse_form_parameters(**kwargs)
99-
kwargs["model"] = SimSirModel(pars)
100-
kwargs["pars"] = pars
101-
102-
callback_returns = []
103-
for component in self.components.values():
104-
try:
105-
callback_returns += component.callback(**kwargs)
106-
except Exception as error:
107-
raise HTMLComponentError(component, error)
108-
109-
return callback_returns
70+
return Div(children=
71+
self.components["navbar"].html
72+
+ [Container(
73+
children=Row(self.components["sidebar"].html + [Div(
74+
id="page-wrapper",
75+
children=self.components["index"].html
76+
)]),
77+
fluid=True,
78+
className="mt-5",
79+
)])

0 commit comments

Comments
 (0)