From 012bcb91a9d740eb354b62ae069062b59ce7fa05 Mon Sep 17 00:00:00 2001 From: alex Date: Tue, 2 Apr 2024 07:18:56 +0200 Subject: [PATCH] first commit --- .gitignore | 3 + .idea/inspectionProfiles/Project_Default.xml | 16 +++++ .../inspectionProfiles/profiles_settings.xml | 6 ++ .idea/misc.xml | 7 ++ .idea/modules.xml | 8 +++ .idea/streamlit userverwaltung.iml | 10 +++ .idea/vcs.xml | 6 ++ .idea/workspace.xml | 63 ++++++++++++++++++ .streamlit/config.toml | 2 + config/users.yml | 50 ++++++++++++++ main.py | 51 +++++++++++++++ pages/dashboard.py | 13 ++++ pages/dashboards.py | 7 ++ pages/test.py | 22 +++++++ pages/user.py | 36 ++++++++++ pages/users.py | 34 ++++++++++ requirements.txt | 46 +++++++++++++ template.py | 65 +++++++++++++++++++ 18 files changed, 445 insertions(+) create mode 100644 .gitignore create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/inspectionProfiles/profiles_settings.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/streamlit userverwaltung.iml create mode 100644 .idea/vcs.xml create mode 100644 .idea/workspace.xml create mode 100644 .streamlit/config.toml create mode 100644 config/users.yml create mode 100644 main.py create mode 100644 pages/dashboard.py create mode 100644 pages/dashboards.py create mode 100644 pages/test.py create mode 100644 pages/user.py create mode 100644 pages/users.py create mode 100644 requirements.txt create mode 100644 template.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e36a0f9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/.venv +/.idea +.gitignore \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..fafe59d --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,16 @@ + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..c96cc30 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..c8a20e7 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/streamlit userverwaltung.iml b/.idea/streamlit userverwaltung.iml new file mode 100644 index 0000000..2c80e12 --- /dev/null +++ b/.idea/streamlit userverwaltung.iml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000..5baad40 --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + { + "associatedIndex": 8 +} + + + + + { + "keyToString": { + "RunOnceActivity.OpenProjectViewOnStart": "true", + "RunOnceActivity.ShowReadmeOnStart": "true" + } +} + + + + + 1711564367379 + + + + \ No newline at end of file diff --git a/.streamlit/config.toml b/.streamlit/config.toml new file mode 100644 index 0000000..74812cd --- /dev/null +++ b/.streamlit/config.toml @@ -0,0 +1,2 @@ +[client] +showSidebarNavigation = false \ No newline at end of file diff --git a/config/users.yml b/config/users.yml new file mode 100644 index 0000000..67624cb --- /dev/null +++ b/config/users.yml @@ -0,0 +1,50 @@ +credentials: + usernames: + jsmith: + email: jsmith@gmail.com + failed_login_attempts: 0 # Will be managed automatically + logged_in: False # Will be managed automatically + name: John Smith + password: abc # Will be hashed automatically + groups: + - admin + - it + rbriggs: + email: rbriggs@gmail.com + failed_login_attempts: 0 # Will be managed automatically + logged_in: False # Will be managed automatically + name: Rebecca Briggs + password: def # Will be hashed automatically +cookie: + expiry_days: 30 + key: some_signature_key # Must be string + name: some_cookie_name +pre-authorized: + emails: + - melsby@gmail.com +groups: + - admin + - it + - dispo + - fuhrpark + - buchhaltung + - service +dashboards: + users: + groups: + - admin + path: pages/users.py + test: + groups: + - admin + - it + path: pages/test.py + test2: + groups: + - it + path: pages/user.py + Dashboard: + groups: + - dispo + - it + path: pages/dashboard.py diff --git a/main.py b/main.py new file mode 100644 index 0000000..bbf7f9f --- /dev/null +++ b/main.py @@ -0,0 +1,51 @@ +import os +import streamlit as st +import streamlit_authenticator as sauth +import numpy as np +import pandas as pd +import yaml +from yaml.loader import SafeLoader +st.set_page_config(layout='wide') + +config = dict() +with open(os.getcwd()+'/config/users.yml') as file: + config = yaml.load(file, Loader=SafeLoader) + +authenticator = sauth.Authenticate( + config['credentials'], + config['cookie']['name'], + config['cookie']['key'], + config['cookie']['expiry_days'], + config['pre-authorized'] +) + +authenticator.login() + + + +if st.session_state["authentication_status"]: + authenticator.logout() + st.session_state['authenticator'] = authenticator +elif st.session_state["authentication_status"] is False: + st.error('Username/password is incorrect') + st.stop() +elif st.session_state["authentication_status"] is None: + st.warning('Please enter your username and password') + st.stop() + + + +st.write('Hello') +st.button('World', use_container_width=True) + +with st.sidebar: + st.button('Hallo') + st.page_link('pages/user.py') + st.page_link('pages/dashboards.py') + st.page_link('pages/dashboard.py') + st.page_link('pages/test.py') + + + + + diff --git a/pages/dashboard.py b/pages/dashboard.py new file mode 100644 index 0000000..a5ee2c6 --- /dev/null +++ b/pages/dashboard.py @@ -0,0 +1,13 @@ +import streamlit as st +import template + +template.authenticate() + +template.make_logout_section() + + +with st.sidebar: + st.write('Hello Daschboard') + + +template.make_dashboard_section() \ No newline at end of file diff --git a/pages/dashboards.py b/pages/dashboards.py new file mode 100644 index 0000000..e3841ca --- /dev/null +++ b/pages/dashboards.py @@ -0,0 +1,7 @@ +import os +import streamlit as st + + +dash_list = [f for f in os.listdir('./pages') if os.path.isfile(os.getcwd()+'/pages/'+f)] + +data = st.data_editor(dash_list) \ No newline at end of file diff --git a/pages/test.py b/pages/test.py new file mode 100644 index 0000000..63fd7a9 --- /dev/null +++ b/pages/test.py @@ -0,0 +1,22 @@ +import os +import yaml +from yaml import SafeLoader +import streamlit as st +import template + +template.authenticate() + +template.make_logout_section() + +template.make_dashboard_section() + +config = dict() +with open(os.getcwd()+'/config/users.yml') as file: + config = yaml.load(file, Loader=SafeLoader) + +st.write(config) +st.write(st.session_state) + +with st.sidebar: + for i in range(20): + st.button('Test'+str(i)) diff --git a/pages/user.py b/pages/user.py new file mode 100644 index 0000000..190300c --- /dev/null +++ b/pages/user.py @@ -0,0 +1,36 @@ +import os +import streamlit as st +import pandas as pd +import template + + +template.authenticate() + +template.make_logout_section() + + +st.title('Benutzer') + +st.header(st.session_state['username']) + +st.divider() + +st.subheader('Info') + +st.text_input('Benutzername', value=st.session_state['username']) +st.text_input('Name', value=st.session_state['name']) +st.text_input('Passwort', type='password', value='Sitch') +st.text_input('Passwort bestätigen:', type='password') + +st.divider() + +st.subheader('Gruppen') + +st.multiselect('Gruppen', template.get_config_groups(), default=template.get_groups()) + +st.divider() + +st.button('Speichern', type='primary') + +st.page_link('pages/users.py', label='Abbrechen') + diff --git a/pages/users.py b/pages/users.py new file mode 100644 index 0000000..c3a1aab --- /dev/null +++ b/pages/users.py @@ -0,0 +1,34 @@ +import os +import json +import streamlit as st +import pandas as pd +import template + + +template.authenticate() + +template.make_logout_section() +def read_config(): + with open(os.getcwd()+"/config/users.json") as file: + + return json.load(file) + +config = read_config() + +st.write(config['users']) + +df_users = pd.DataFrame(config['users']) + +st.header('Benutzerverwaltung') + +col1, col2, col3 = st.columns(3) + +with col1: + pass + +with col2: + st.metric('Benutzer Gesamt', 10, 20) + +edited_df = st.data_editor(df_users, hide_index=True, use_container_width=True, num_rows="dynamic") + +st.write(edited_df) \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..19c4b50 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,46 @@ +altair==5.2.0 +attrs==23.2.0 +bcrypt==4.1.2 +blinker==1.7.0 +cachetools==5.3.3 +certifi==2024.2.2 +charset-normalizer==3.3.2 +click==8.1.7 +extra-streamlit-components==0.1.71 +gitdb==4.0.11 +GitPython==3.1.42 +idna==3.6 +Jinja2==3.1.3 +jsonschema==4.21.1 +jsonschema-specifications==2023.12.1 +markdown-it-py==3.0.0 +MarkupSafe==2.1.5 +mdurl==0.1.2 +numpy==1.26.4 +packaging==23.2 +pandas==2.2.1 +pillow==10.2.0 +protobuf==4.25.3 +pyarrow==15.0.2 +pydeck==0.8.1b0 +Pygments==2.17.2 +PyJWT==2.8.0 +python-dateutil==2.9.0.post0 +pytz==2024.1 +PyYAML==6.0.1 +referencing==0.34.0 +requests==2.31.0 +rich==13.7.1 +rpds-py==0.18.0 +six==1.16.0 +smmap==5.0.1 +streamlit==1.32.2 +streamlit-authenticator==0.3.2 +tenacity==8.2.3 +toml==0.10.2 +toolz==0.12.1 +tornado==6.4 +typing_extensions==4.10.0 +tzdata==2024.1 +urllib3==2.2.1 +watchdog==4.0.0 diff --git a/template.py b/template.py new file mode 100644 index 0000000..45bef7e --- /dev/null +++ b/template.py @@ -0,0 +1,65 @@ +import os +import streamlit as st +import yaml +from yaml.loader import SafeLoader + +config = None +def get_config(): + global config + if config is None: + with open(os.getcwd()+'/config/users.yml') as file: + config = yaml.load(file, Loader=SafeLoader) + return config + +def authenticate(): + try: + if st.session_state["authentication_status"]: + pass + else: + print('Not authenticated') + st.switch_page('main.py') + except KeyError: + print('No Key found') + st.switch_page('main.py') + +def make_logout_section(): + with st.sidebar: + st.write("Hallo " + st.session_state['name']) + st.page_link('pages/user.py', label='Benutzer') + st.page_link('main.py', label='Hauptseite') + st.session_state['authenticator'].logout() + st.divider() + + +def get_config_groups(): + config = get_config() + groups = config['groups'] + return groups + +def get_config_dashboards(): + config = get_config() + dashboards = config['dashboards'] + return dashboards + +def get_groups(): + config = get_config() + user = config['credentials']['usernames'][st.session_state['username']] + groups = user['groups'] + return groups + +def get_dashboards(): + config = get_config() + groups = get_groups() + dashboards = set() + dash = config['dashboards'] + for d in dash: + for dg in dash[d]['groups']: + if dg in groups: + dashboards.add(d) + return dashboards + +def make_dashboard_section(): + with st.sidebar: + dashboards = get_config_dashboards() + for d in get_dashboards(): + st.page_link(dashboards[d]['path'], label=d)