pumpwood_streamlit.dashboard
Dashboard class to use as base from Pumpwood Streamlit Dashboards.
1"""Dashboard class to use as base from Pumpwood Streamlit Dashboards.""" 2import os 3import streamlit as st 4import extra_streamlit_components as stx 5from abc import ABC, abstractmethod 6from pumpwood_communication.microservices import PumpWoodMicroService 7 8 9def _get_cookie_manager(): 10 """Retrieve Cookie Manager.""" 11 return stx.CookieManager() 12 13 14class PumpwoodStreamlitDashboard(ABC): 15 """Abstract Class to facilitate criation of Streamlit Dashboards.""" 16 17 def __init__(self, microservice: PumpWoodMicroService = None): 18 """ 19 __init__. 20 21 It is possible to init object with a microservice to help 22 building dashboard. 23 24 If microservice=None (production deploy), `__init__` will create an 25 unlogged microservice object using `MICROSERVICE_URL` from enviroment 26 variable. Authentication validation function will set attribute 27 `_auth_token` with `PumpwoodAuthorization` token that can be used 28 to user impersonation. 29 30 Args: 31 microservice: 32 An microservice can be passed to object for developing 33 and debug. 34 """ 35 # Set auth_header to None, this will permit dev microservice to 36 # use credencials and prod get auth header from cookie 37 self._auth_token = None 38 if microservice is not None: 39 self._microservice = microservice 40 else: 41 MICROSERVICE_URL = os.getenv("MICROSERVICE_URL") 42 if MICROSERVICE_URL is not None: 43 self._microservice = PumpWoodMicroService( 44 name="dashboard-microservice", 45 server_url=MICROSERVICE_URL) 46 else: 47 msg = ( 48 "'microservice' is not set as argument and " + 49 "'MICROSERVICE_URL' not set as enviroment variable") 50 raise Exception(msg) 51 52 def validate_authentication(self) -> bool: 53 """ 54 Validate authentication using cookie with PumpwoodAuthorization. 55 56 Returns: 57 Return True if user is logged on Pumpwood and False if token 58 set at PumpwoodAuthorization is invalid. 59 """ 60 cookie_manager = _get_cookie_manager() 61 cookie_auth_token = cookie_manager.get('PumpwoodAuthorization') 62 if cookie_auth_token is not None: 63 self._auth_token = {"Authorization": 'Token ' + cookie_auth_token} 64 65 is_logged = self._microservice.check_if_logged( 66 auth_header=self._auth_token) 67 return is_logged 68 69 def authentication_error_page(self) -> None: 70 """ 71 Set the authentication error page. 72 73 This function is called if self.validate_login() return False. 74 75 Example: 76 ```python 77 st.title('User token is invalid, log in again to refresh token.') 78 ``` 79 """ 80 st.title('User token is invalid, log in again to refresh token.') 81 82 def run(self) -> None: 83 """ 84 Render Streamlit dashboard. 85 86 This function is used as an entry point for app.py Streamlit 87 dashboard. 88 89 Most of the cases should not be reimplemented. It is important 90 that if reimplemented `is_logged = self.validate_authentication()` 91 function must be called at the beggin to assure that user is 92 authenticated on Pumpwood. 93 94 Example of an app.py: 95 ``` 96 import os 97 from dashboard import Dashboard 98 from pumpwood_communication.microservices import PumpWoodMicroService 99 100 ############################################################### 101 # Read env variables to be used on local test of the dashboard. 102 # Passing a logged microservice to dashboard will disable 103 # authentication 104 # !!! DO NOT USE AUTHENTICATED MICROSERVICE IN PRODUCTION 105 # DASHBOARDS !!! # 106 MICROSERVICE_URL = os.getenv('MICROSERVICE_URL') 107 MICROSERVICE_DASHBOARD_USERNAME = os.getenv( 108 'MICROSERVICE_DASHBOARD_USERNAME') 109 MICROSERVICE_DASHBOARD_PASSWORD = os.getenv( 110 'MICROSERVICE_DASHBOARD_PASSWORD') 111 112 microservice = None 113 if MICROSERVICE_DASHBOARD_USERNAME is not None: 114 microservice = PumpWoodMicroService( 115 name="dashboard-microservice", 116 server_url=MICROSERVICE_URL, 117 username=MICROSERVICE_DASHBOARD_USERNAME, 118 password=MICROSERVICE_DASHBOARD_PASSWORD,) 119 microservice.login() 120 121 dash_obj = Dashboard(microservice=microservice) 122 dash_obj.run() 123 ``` 124 125 Implemented run function: 126 ```python 127 def run(self) -> None: 128 # Set page configuration 129 self.set_page_config() 130 131 # Validate auth_header 132 is_logged = self.validate_authentication() 133 if not is_logged: 134 # Authorization error 135 self.authentication_error_page() 136 else: 137 # Render main Dashboard View 138 self.main_view() 139 ``` 140 """ 141 # Set page configuration 142 self.set_page_config() 143 144 # Validate auth_header 145 is_logged = self.validate_authentication() 146 if not is_logged: 147 # Authorization error 148 self.authentication_error_page() 149 else: 150 # Render main Dashboard View 151 self.main_view() 152 153 @abstractmethod 154 def set_page_config(self) -> None: 155 """ 156 Set page config, must be implemented. 157 158 Exemple: 159 ```python 160 st.set_page_config( 161 page_title="US Population Dashboard", 162 page_icon="🏂", 163 layout="wide", 164 initial_sidebar_state="expanded") 165 ``` 166 """ 167 msg = "'set_page_config' function must be implemented" 168 raise NotImplementedError(msg) 169 170 @abstractmethod 171 def main_view(self) -> None: 172 """ 173 Render main dashboard view. 174 175 Exemple: 176 ```python 177 st.set_page_config( 178 page_title="US Population Dashboard", 179 page_icon="🏂", 180 layout="wide", 181 initial_sidebar_state="expanded") 182 ``` 183 """ 184 msg = "'main_view' function must be implemented" 185 raise NotImplementedError(msg)
15class PumpwoodStreamlitDashboard(ABC): 16 """Abstract Class to facilitate criation of Streamlit Dashboards.""" 17 18 def __init__(self, microservice: PumpWoodMicroService = None): 19 """ 20 __init__. 21 22 It is possible to init object with a microservice to help 23 building dashboard. 24 25 If microservice=None (production deploy), `__init__` will create an 26 unlogged microservice object using `MICROSERVICE_URL` from enviroment 27 variable. Authentication validation function will set attribute 28 `_auth_token` with `PumpwoodAuthorization` token that can be used 29 to user impersonation. 30 31 Args: 32 microservice: 33 An microservice can be passed to object for developing 34 and debug. 35 """ 36 # Set auth_header to None, this will permit dev microservice to 37 # use credencials and prod get auth header from cookie 38 self._auth_token = None 39 if microservice is not None: 40 self._microservice = microservice 41 else: 42 MICROSERVICE_URL = os.getenv("MICROSERVICE_URL") 43 if MICROSERVICE_URL is not None: 44 self._microservice = PumpWoodMicroService( 45 name="dashboard-microservice", 46 server_url=MICROSERVICE_URL) 47 else: 48 msg = ( 49 "'microservice' is not set as argument and " + 50 "'MICROSERVICE_URL' not set as enviroment variable") 51 raise Exception(msg) 52 53 def validate_authentication(self) -> bool: 54 """ 55 Validate authentication using cookie with PumpwoodAuthorization. 56 57 Returns: 58 Return True if user is logged on Pumpwood and False if token 59 set at PumpwoodAuthorization is invalid. 60 """ 61 cookie_manager = _get_cookie_manager() 62 cookie_auth_token = cookie_manager.get('PumpwoodAuthorization') 63 if cookie_auth_token is not None: 64 self._auth_token = {"Authorization": 'Token ' + cookie_auth_token} 65 66 is_logged = self._microservice.check_if_logged( 67 auth_header=self._auth_token) 68 return is_logged 69 70 def authentication_error_page(self) -> None: 71 """ 72 Set the authentication error page. 73 74 This function is called if self.validate_login() return False. 75 76 Example: 77 ```python 78 st.title('User token is invalid, log in again to refresh token.') 79 ``` 80 """ 81 st.title('User token is invalid, log in again to refresh token.') 82 83 def run(self) -> None: 84 """ 85 Render Streamlit dashboard. 86 87 This function is used as an entry point for app.py Streamlit 88 dashboard. 89 90 Most of the cases should not be reimplemented. It is important 91 that if reimplemented `is_logged = self.validate_authentication()` 92 function must be called at the beggin to assure that user is 93 authenticated on Pumpwood. 94 95 Example of an app.py: 96 ``` 97 import os 98 from dashboard import Dashboard 99 from pumpwood_communication.microservices import PumpWoodMicroService 100 101 ############################################################### 102 # Read env variables to be used on local test of the dashboard. 103 # Passing a logged microservice to dashboard will disable 104 # authentication 105 # !!! DO NOT USE AUTHENTICATED MICROSERVICE IN PRODUCTION 106 # DASHBOARDS !!! # 107 MICROSERVICE_URL = os.getenv('MICROSERVICE_URL') 108 MICROSERVICE_DASHBOARD_USERNAME = os.getenv( 109 'MICROSERVICE_DASHBOARD_USERNAME') 110 MICROSERVICE_DASHBOARD_PASSWORD = os.getenv( 111 'MICROSERVICE_DASHBOARD_PASSWORD') 112 113 microservice = None 114 if MICROSERVICE_DASHBOARD_USERNAME is not None: 115 microservice = PumpWoodMicroService( 116 name="dashboard-microservice", 117 server_url=MICROSERVICE_URL, 118 username=MICROSERVICE_DASHBOARD_USERNAME, 119 password=MICROSERVICE_DASHBOARD_PASSWORD,) 120 microservice.login() 121 122 dash_obj = Dashboard(microservice=microservice) 123 dash_obj.run() 124 ``` 125 126 Implemented run function: 127 ```python 128 def run(self) -> None: 129 # Set page configuration 130 self.set_page_config() 131 132 # Validate auth_header 133 is_logged = self.validate_authentication() 134 if not is_logged: 135 # Authorization error 136 self.authentication_error_page() 137 else: 138 # Render main Dashboard View 139 self.main_view() 140 ``` 141 """ 142 # Set page configuration 143 self.set_page_config() 144 145 # Validate auth_header 146 is_logged = self.validate_authentication() 147 if not is_logged: 148 # Authorization error 149 self.authentication_error_page() 150 else: 151 # Render main Dashboard View 152 self.main_view() 153 154 @abstractmethod 155 def set_page_config(self) -> None: 156 """ 157 Set page config, must be implemented. 158 159 Exemple: 160 ```python 161 st.set_page_config( 162 page_title="US Population Dashboard", 163 page_icon="🏂", 164 layout="wide", 165 initial_sidebar_state="expanded") 166 ``` 167 """ 168 msg = "'set_page_config' function must be implemented" 169 raise NotImplementedError(msg) 170 171 @abstractmethod 172 def main_view(self) -> None: 173 """ 174 Render main dashboard view. 175 176 Exemple: 177 ```python 178 st.set_page_config( 179 page_title="US Population Dashboard", 180 page_icon="🏂", 181 layout="wide", 182 initial_sidebar_state="expanded") 183 ``` 184 """ 185 msg = "'main_view' function must be implemented" 186 raise NotImplementedError(msg)
Abstract Class to facilitate criation of Streamlit Dashboards.
18 def __init__(self, microservice: PumpWoodMicroService = None): 19 """ 20 __init__. 21 22 It is possible to init object with a microservice to help 23 building dashboard. 24 25 If microservice=None (production deploy), `__init__` will create an 26 unlogged microservice object using `MICROSERVICE_URL` from enviroment 27 variable. Authentication validation function will set attribute 28 `_auth_token` with `PumpwoodAuthorization` token that can be used 29 to user impersonation. 30 31 Args: 32 microservice: 33 An microservice can be passed to object for developing 34 and debug. 35 """ 36 # Set auth_header to None, this will permit dev microservice to 37 # use credencials and prod get auth header from cookie 38 self._auth_token = None 39 if microservice is not None: 40 self._microservice = microservice 41 else: 42 MICROSERVICE_URL = os.getenv("MICROSERVICE_URL") 43 if MICROSERVICE_URL is not None: 44 self._microservice = PumpWoodMicroService( 45 name="dashboard-microservice", 46 server_url=MICROSERVICE_URL) 47 else: 48 msg = ( 49 "'microservice' is not set as argument and " + 50 "'MICROSERVICE_URL' not set as enviroment variable") 51 raise Exception(msg)
__init__.
It is possible to init object with a microservice to help building dashboard.
If microservice=None (production deploy), __init__ will create an
unlogged microservice object using MICROSERVICE_URL from enviroment
variable. Authentication validation function will set attribute
_auth_token with PumpwoodAuthorization token that can be used
to user impersonation.
Arguments:
- microservice: An microservice can be passed to object for developing and debug.
53 def validate_authentication(self) -> bool: 54 """ 55 Validate authentication using cookie with PumpwoodAuthorization. 56 57 Returns: 58 Return True if user is logged on Pumpwood and False if token 59 set at PumpwoodAuthorization is invalid. 60 """ 61 cookie_manager = _get_cookie_manager() 62 cookie_auth_token = cookie_manager.get('PumpwoodAuthorization') 63 if cookie_auth_token is not None: 64 self._auth_token = {"Authorization": 'Token ' + cookie_auth_token} 65 66 is_logged = self._microservice.check_if_logged( 67 auth_header=self._auth_token) 68 return is_logged
Validate authentication using cookie with PumpwoodAuthorization.
Returns:
Return True if user is logged on Pumpwood and False if token set at PumpwoodAuthorization is invalid.
70 def authentication_error_page(self) -> None: 71 """ 72 Set the authentication error page. 73 74 This function is called if self.validate_login() return False. 75 76 Example: 77 ```python 78 st.title('User token is invalid, log in again to refresh token.') 79 ``` 80 """ 81 st.title('User token is invalid, log in again to refresh token.')
Set the authentication error page.
This function is called if self.validate_login() return False.
Example:
st.title('User token is invalid, log in again to refresh token.')
83 def run(self) -> None: 84 """ 85 Render Streamlit dashboard. 86 87 This function is used as an entry point for app.py Streamlit 88 dashboard. 89 90 Most of the cases should not be reimplemented. It is important 91 that if reimplemented `is_logged = self.validate_authentication()` 92 function must be called at the beggin to assure that user is 93 authenticated on Pumpwood. 94 95 Example of an app.py: 96 ``` 97 import os 98 from dashboard import Dashboard 99 from pumpwood_communication.microservices import PumpWoodMicroService 100 101 ############################################################### 102 # Read env variables to be used on local test of the dashboard. 103 # Passing a logged microservice to dashboard will disable 104 # authentication 105 # !!! DO NOT USE AUTHENTICATED MICROSERVICE IN PRODUCTION 106 # DASHBOARDS !!! # 107 MICROSERVICE_URL = os.getenv('MICROSERVICE_URL') 108 MICROSERVICE_DASHBOARD_USERNAME = os.getenv( 109 'MICROSERVICE_DASHBOARD_USERNAME') 110 MICROSERVICE_DASHBOARD_PASSWORD = os.getenv( 111 'MICROSERVICE_DASHBOARD_PASSWORD') 112 113 microservice = None 114 if MICROSERVICE_DASHBOARD_USERNAME is not None: 115 microservice = PumpWoodMicroService( 116 name="dashboard-microservice", 117 server_url=MICROSERVICE_URL, 118 username=MICROSERVICE_DASHBOARD_USERNAME, 119 password=MICROSERVICE_DASHBOARD_PASSWORD,) 120 microservice.login() 121 122 dash_obj = Dashboard(microservice=microservice) 123 dash_obj.run() 124 ``` 125 126 Implemented run function: 127 ```python 128 def run(self) -> None: 129 # Set page configuration 130 self.set_page_config() 131 132 # Validate auth_header 133 is_logged = self.validate_authentication() 134 if not is_logged: 135 # Authorization error 136 self.authentication_error_page() 137 else: 138 # Render main Dashboard View 139 self.main_view() 140 ``` 141 """ 142 # Set page configuration 143 self.set_page_config() 144 145 # Validate auth_header 146 is_logged = self.validate_authentication() 147 if not is_logged: 148 # Authorization error 149 self.authentication_error_page() 150 else: 151 # Render main Dashboard View 152 self.main_view()
Render Streamlit dashboard.
This function is used as an entry point for app.py Streamlit dashboard.
Most of the cases should not be reimplemented. It is important
that if reimplemented is_logged = self.validate_authentication()
function must be called at the beggin to assure that user is
authenticated on Pumpwood.
Example of an app.py:
import os
from dashboard import Dashboard
from pumpwood_communication.microservices import PumpWoodMicroService
###############################################################
# Read env variables to be used on local test of the dashboard.
# Passing a logged microservice to dashboard will disable
# authentication
# !!! DO NOT USE AUTHENTICATED MICROSERVICE IN PRODUCTION
# DASHBOARDS !!! #
MICROSERVICE_URL = os.getenv('MICROSERVICE_URL')
MICROSERVICE_DASHBOARD_USERNAME = os.getenv(
'MICROSERVICE_DASHBOARD_USERNAME')
MICROSERVICE_DASHBOARD_PASSWORD = os.getenv(
'MICROSERVICE_DASHBOARD_PASSWORD')
microservice = None
if MICROSERVICE_DASHBOARD_USERNAME is not None:
microservice = PumpWoodMicroService(
name="dashboard-microservice",
server_url=MICROSERVICE_URL,
username=MICROSERVICE_DASHBOARD_USERNAME,
password=MICROSERVICE_DASHBOARD_PASSWORD,)
microservice.login()
dash_obj = Dashboard(microservice=microservice)
dash_obj.run()
Implemented run function:
def run(self) -> None:
# Set page configuration
self.set_page_config()
# Validate auth_header
is_logged = self.validate_authentication()
if not is_logged:
# Authorization error
self.authentication_error_page()
else:
# Render main Dashboard View
self.main_view()
154 @abstractmethod 155 def set_page_config(self) -> None: 156 """ 157 Set page config, must be implemented. 158 159 Exemple: 160 ```python 161 st.set_page_config( 162 page_title="US Population Dashboard", 163 page_icon="🏂", 164 layout="wide", 165 initial_sidebar_state="expanded") 166 ``` 167 """ 168 msg = "'set_page_config' function must be implemented" 169 raise NotImplementedError(msg)
Set page config, must be implemented.
Exemple:
st.set_page_config(
page_title="US Population Dashboard",
page_icon="🏂",
layout="wide",
initial_sidebar_state="expanded")
171 @abstractmethod 172 def main_view(self) -> None: 173 """ 174 Render main dashboard view. 175 176 Exemple: 177 ```python 178 st.set_page_config( 179 page_title="US Population Dashboard", 180 page_icon="🏂", 181 layout="wide", 182 initial_sidebar_state="expanded") 183 ``` 184 """ 185 msg = "'main_view' function must be implemented" 186 raise NotImplementedError(msg)
Render main dashboard view.
Exemple:
st.set_page_config(
page_title="US Population Dashboard",
page_icon="🏂",
layout="wide",
initial_sidebar_state="expanded")