From 071f83b6bf40391ba2c27bd0067cadc362bc5116 Mon Sep 17 00:00:00 2001 From: Leah Tacke genannt Unterberg <leah.tgu@pads.rwth-aachen.de> Date: Mon, 12 Jun 2023 11:40:16 +0200 Subject: [PATCH] updated dockerfile --- Dockerfile | 24 +++++++-------------- DockerfilePoetry | 51 ++++++++++++++++++++++++++++++++++++++++++++ environment.yml | 14 ++++++++++++ logic/page_logic.py | 43 ++++++++++++++++++++++++------------- pages/demo_page.py | 2 +- pages/upload_page.py | 2 +- poetry.lock | 12 +++++------ pyproject.toml | 2 +- 8 files changed, 110 insertions(+), 40 deletions(-) create mode 100644 DockerfilePoetry create mode 100644 environment.yml diff --git a/Dockerfile b/Dockerfile index 8e7f555..085e880 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.9-slim as base +FROM continuumio/miniconda3:latest as conda ENV PYTHONFAULTHANDLER=1 \ PYTHONHASHSEED=random \ @@ -6,14 +6,12 @@ ENV PYTHONFAULTHANDLER=1 \ WORKDIR /app -FROM base as builder +FROM conda as builder ENV PIP_DEFAULT_TIMEOUT=100 \ PIP_DISABLE_PIP_VERSION_CHECK=1 \ - PIP_NO_CACHE_DIR=1 \ - POETRY_VERSION=1.4 + PIP_NO_CACHE_DIR=1 -RUN pip install "poetry==$POETRY_VERSION" RUN apt-get update && apt-get install -y \ build-essential \ @@ -29,23 +27,17 @@ RUN apt-get update && apt-get install -y \ COPY logic/ logic/ COPY pages/ pages/ COPY resources/ resources/ -COPY poetry.lock pyproject.toml streamlit_app.py ./ +COPY poetry.lock pyproject.toml environment.yml streamlit_app.py ./ -RUN poetry config virtualenvs.in-project true && \ - poetry install --only=main --no-root && \ - poetry build +RUN conda env create -f "environment.yml" -FROM base as final -COPY --from=builder /app/.venv ./.venv -COPY --from=builder /app/dist . -COPY docker-entrypoint.sh . - -RUN ./.venv/bin/pip install *.whl +FROM builder as final EXPOSE 8501 HEALTHCHECK CMD curl --fail http://localhost:8501/_stcore/health +SHELL ["conda", "run", "-n", "mdata-app", "/bin/bash", "-c"] # CMD ["./docker-entrypoint.sh"] -ENTRYPOINT ["streamlit", "run", "streamlit_app.py", "--server.port=8501", "--server.address=0.0.0.0"] \ No newline at end of file +ENTRYPOINT ["conda", "run", "--no-capture-output", "-n", "mdata-app", "streamlit", "run", "streamlit_app.py", "--server.port=8501", "--server.address=0.0.0.0"] \ No newline at end of file diff --git a/DockerfilePoetry b/DockerfilePoetry new file mode 100644 index 0000000..8e7f555 --- /dev/null +++ b/DockerfilePoetry @@ -0,0 +1,51 @@ +FROM python:3.9-slim as base + +ENV PYTHONFAULTHANDLER=1 \ + PYTHONHASHSEED=random \ + PYTHONUNBUFFERED=1 + +WORKDIR /app + +FROM base as builder + +ENV PIP_DEFAULT_TIMEOUT=100 \ + PIP_DISABLE_PIP_VERSION_CHECK=1 \ + PIP_NO_CACHE_DIR=1 \ + POETRY_VERSION=1.4 + +RUN pip install "poetry==$POETRY_VERSION" + +RUN apt-get update && apt-get install -y \ + build-essential \ + curl \ + software-properties-common \ + git \ + python3-dev \ + libblas-dev \ + liblapack-dev \ + && rm -rf /var/lib/apt/lists/* + +# RUN git clone https://git-ce.rwth-aachen.de/leah.tgu/mdata_app.git . +COPY logic/ logic/ +COPY pages/ pages/ +COPY resources/ resources/ +COPY poetry.lock pyproject.toml streamlit_app.py ./ + +RUN poetry config virtualenvs.in-project true && \ + poetry install --only=main --no-root && \ + poetry build + +FROM base as final + +COPY --from=builder /app/.venv ./.venv +COPY --from=builder /app/dist . +COPY docker-entrypoint.sh . + +RUN ./.venv/bin/pip install *.whl + +EXPOSE 8501 + +HEALTHCHECK CMD curl --fail http://localhost:8501/_stcore/health + +# CMD ["./docker-entrypoint.sh"] +ENTRYPOINT ["streamlit", "run", "streamlit_app.py", "--server.port=8501", "--server.address=0.0.0.0"] \ No newline at end of file diff --git a/environment.yml b/environment.yml new file mode 100644 index 0000000..dbca17a --- /dev/null +++ b/environment.yml @@ -0,0 +1,14 @@ +name: mdata-app + +dependencies: + - python=3.10 + - numpy + - matplotlib + - seaborn + - plotly + - pandas + - pip + - pip: + - tsdownsample + - streamlit + - git+https://git-ce.rwth-aachen.de/leah.tgu/mdata@develop \ No newline at end of file diff --git a/logic/page_logic.py b/logic/page_logic.py index fa1359d..5c3c8df 100644 --- a/logic/page_logic.py +++ b/logic/page_logic.py @@ -2,6 +2,7 @@ from enum import Enum import pandas as pd import streamlit as st +from mdata.core import mdd from mdata.visualization import plotting, matplot class Widgets(Enum): @@ -11,9 +12,9 @@ class Widgets(Enum): Inspector = 'Inspector' Dummy = 'Dummy' -available_widgets = list(Widgets) +available_widgets = [w for w in Widgets] -def generate_page(md, widget): +def generate_page(md: mdd.MachineData, widget): c = st.columns(3) c[0].metric('#Observations', len(md.index_frame)) c[1].metric('#Event Types', len(md.event_series_types)) @@ -27,30 +28,40 @@ def generate_page(md, widget): cont.text(md.index_frame['time'].max()) cont.caption('Last Observation') - if widget not in Widgets: - return - if widget == Widgets.Specifications: st.markdown('## Events') st.table(make_spec_df(md.event_series_types)) st.markdown('## Measurements') st.table(make_spec_df(md.measurement_series_types)) - - if widget == Widgets.RawData: - st.markdown('## Index') - st.write(md.index_frame) - - if widget == Widgets.Overview: + fig = plotting.create_measurement_frequency_plot(md) + st.plotly_chart(fig) + + elif widget == Widgets.RawData: + + c1, c2 = st.columns(2) + with c1: + st.markdown('## Index') + st.write(md.index_frame) + with c2: + selection = st.selectbox('Observation Type', [tsc.timeseries_type.type + ':' + tsc.timeseries_type.label for tsc in md.iter_all_timeseries()]) + if selection is not None: + label = selection[2:] + if selection[0] == 'E': + st.write(md.get_event_series_collection(label).df) + if selection[0] == 'M': + st.write(md.get_measurement_series_collection(label).df) + + elif widget == Widgets.Overview: f = plotting.create_overview_plot(md, downsample_to=5_000) st.plotly_chart(f, use_container_width=True) - if widget == Widgets.Inspector: + elif widget == Widgets.Inspector: c1, c2, c3 = st.columns(3) - object_list = list(md.get_unique_objects()) event_type_list = list(md.event_series_types.keys()) measurement_type_list = list(md.measurement_series_types.keys()) selected_measurement_type = c1.selectbox('Measurement Type', measurement_type_list) - fs = md.measurement_series_types[selected_measurement_type].features + fs = list(md.measurement_series_types[selected_measurement_type].features) + object_list = list(md.measurement_series[selected_measurement_type].occurring_objects) measurement_feature_selection = c1.multiselect('Feature Selection', fs) event_selection = c2.multiselect('Event Type Selection', event_type_list) @@ -64,12 +75,14 @@ def generate_page(md, widget): st.plotly_chart(f, use_container_width=True) - if widget == Widgets.Dummy: + elif widget == Widgets.Dummy: measurement_type_list = list(md.measurement_series_types.keys()) selected_measurement_type = st.selectbox('Measurement Type', measurement_type_list) f = matplot.create_basic_stacked_subplots(md, measurement_type=selected_measurement_type) st.write(f) + else: + st.write('Invalid Widget') def make_spec_df(spec_types): df = pd.DataFrame.from_dict({l: list(t.features) for l, t in spec_types.items()}, diff --git a/pages/demo_page.py b/pages/demo_page.py index 3bf56db..f7a499e 100644 --- a/pages/demo_page.py +++ b/pages/demo_page.py @@ -10,5 +10,5 @@ def load_data(): md = load_data() -selected_widget = st.sidebar.selectbox('Widget', available_widgets) +selected_widget = st.sidebar.selectbox('Widget', available_widgets, format_func=lambda w: w.value) generate_page(md, selected_widget) diff --git a/pages/upload_page.py b/pages/upload_page.py index 2418055..bf4e3dc 100644 --- a/pages/upload_page.py +++ b/pages/upload_page.py @@ -54,7 +54,7 @@ def attempt_import(import_type, **files): md = attempt_import(import_type, **files) -selected_widget = st.sidebar.selectbox('Widget', available_widgets) +selected_widget = st.sidebar.selectbox('Widget', available_widgets, format_func=lambda w: w.value) if md is not None: st.session_state['uploaded_md'] = md diff --git a/poetry.lock b/poetry.lock index a810780..777ef40 100644 --- a/poetry.lock +++ b/poetry.lock @@ -817,14 +817,14 @@ tests = ["asttokens", "littleutils", "pytest", "rich"] [[package]] name = "fastjsonschema" -version = "2.16.3" +version = "2.17.1" description = "Fastest Python implementation of JSON schema" category = "main" optional = false python-versions = "*" files = [ - {file = "fastjsonschema-2.16.3-py3-none-any.whl", hash = "sha256:04fbecc94300436f628517b05741b7ea009506ce8f946d40996567c669318490"}, - {file = "fastjsonschema-2.16.3.tar.gz", hash = "sha256:4a30d6315a68c253cfa8f963b9697246315aa3db89f98b97235e345dedfb0b8e"}, + {file = "fastjsonschema-2.17.1-py3-none-any.whl", hash = "sha256:4b90b252628ca695280924d863fe37234eebadc29c5360d322571233dc9746e0"}, + {file = "fastjsonschema-2.17.1.tar.gz", hash = "sha256:f4eeb8a77cef54861dbf7424ac8ce71306f12cbb086c45131bcba2c6a4f726e3"}, ] [package.extras] @@ -3704,14 +3704,14 @@ files = [ [[package]] name = "websocket-client" -version = "1.5.1" +version = "1.5.2" description = "WebSocket client for Python with low level API options" category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "websocket-client-1.5.1.tar.gz", hash = "sha256:3f09e6d8230892547132177f575a4e3e73cfdf06526e20cc02aa1c3b47184d40"}, - {file = "websocket_client-1.5.1-py3-none-any.whl", hash = "sha256:cdf5877568b7e83aa7cf2244ab56a3213de587bbe0ce9d8b9600fc77b455d89e"}, + {file = "websocket-client-1.5.2.tar.gz", hash = "sha256:c7d67c13b928645f259d9b847ab5b57fd2d127213ca41ebd880de1f553b7c23b"}, + {file = "websocket_client-1.5.2-py3-none-any.whl", hash = "sha256:f8c64e28cd700e7ba1f04350d66422b6833b82a796b525a51e740b8cc8dab4b1"}, ] [package.extras] diff --git a/pyproject.toml b/pyproject.toml index 02777e8..c2e3b1e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,7 +14,7 @@ cvxopt = "^1.3" streamlit = "^1.21" # mdata = "^0.1.0" mdata = { path = "C:/Users/Leah/PycharmProjects/mdata", develop = true } -#mdata = { git = "https://git-ce.rwth-aachen.de/leah.tgu/mdata.git", branch = "master" } +# mdata = { git = "https://git-ce.rwth-aachen.de/leah.tgu/mdata.git", branch = "master" } seaborn = "^0.12.2" plotly = "^5.14.1" tsdownsample = "^0.1.2" -- GitLab