A secure authentication module to validate user credentials in a Streamlit application
Streamlit-Authenticator is distributed via PyPI:
pip install streamlit-authenticator
Using Streamlit-Authenticator is as simple as importing the module and calling it to verify your predefined users' credentials.
import streamlit as st
import streamlit_authenticator as stauth
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
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
_Please note that the 'loggedin' field corresponding to each user's log-in status will be added automatically.
import yaml
from yaml.loader import SafeLoader
with open('../config.yaml') as file:
config = yaml.load(file, Loader=SafeLoader)
authenticator = stauth.Authenticate(
config['credentials'],
config['cookie']['name'],
config['cookie']['key'],
config['cookie']['expiry_days'],
config['pre-authorized']
)
Authenticate
Parameters:
- credentials: dict
- Provides the usernames, names, passwords, and emails, and other user data.
- cookie_name: str
- Specifies the name of the re-authentication cookie stored on the client's browser for password-less re-authentication.
- cookie_key: str
- Specifies the key that will be used to hash the signature of the re-authentication cookie.
- cookie_expiry_days: float, default 30.0
- Specifies the number of days before the re-authentication cookie automatically expires on the client's browser.
- pre-authorized: list, default None
- Provides the list of emails of unregistered users who are authorized to register.
- validator: object, default None
- Provides a validator object that will check the validity of the username, name, and email fields.
authenticator.login()
Authenticate.login
Parameters:
- location: str, {'main', 'sidebar'}, default 'main'
- Specifies the location of the login widget.
- max_concurrent_users: int, default None
- Limits the number of concurrent users. If not specified there will be no limit to the number of users.
- max_login_attempts: int, default None
- Limits the number of failed login attempts. If not specified there will be no limit to the number of failed login attempts.
- fields: dict, default {'Form name':'Login', 'Username':'Username', 'Password':'Password', 'Login':'Login'}
- Customizes the text of headers, buttons and other fields.
- clear_on_submit: bool, default False
- Specifies the clear on submit setting, True: clears inputs on submit, False: keeps inputs on submit.
Returns:
- str
- Name of the authenticated user.
- bool
- Status of authentication, None: no credentials entered, False: incorrect credentials, True: correct credentials.
- str
- Username of the authenticated user.
if st.session_state["authentication_status"]:
authenticator.logout()
st.write(f'Welcome *{st.session_state["name"]}*')
st.title('Some content')
elif st.session_state["authentication_status"] is False:
st.error('Username/password is incorrect')
elif st.session_state["authentication_status"] is None:
st.warning('Please enter your username and password')
Authenticate.logout
Parameters:
- button_name: str, default 'Logout'
- Customizes the button name.
- location: str, {'main', 'sidebar','unrendered'}, default 'main'
- Specifies the location of the logout button. If 'unrendered' is passed, the logout logic will be executed without rendering the button.
- key: str, default None
- Unique key that should be used in multi-page applications.
if st.session_state["authentication_status"]:
try:
if authenticator.reset_password(st.session_state["username"]):
st.success('Password modified successfully')
except Exception as e:
st.error(e)
Authenticate.reset_password
Parameters:
- username: str
- Specifies the username of the user to reset the password for.
- location: str, {'main', 'sidebar'}, default 'main'
- Specifies the location of the reset password widget.
- fields: dict, default {'Form name':'Reset password', 'Current password':'Current password', 'New password':'New password', 'Repeat password': 'Repeat password', 'Reset':'Reset'}
- Customizes the text of headers, buttons and other fields.
- clear_on_submit: bool, default False
- Specifies the clear on submit setting, True: clears inputs on submit, False: keeps inputs on submit.
Returns::
- bool
- Status of resetting the password.
Please remember to update the config file (as shown in step 9) after you use this widget.
try:
email_of_registered_user, username_of_registered_user, name_of_registered_user = authenticator.register_user(pre_authorization=False)
if email_of_registered_user:
st.success('User registered successfully')
except Exception as e:
st.error(e)
Authenticate.register_user
Parameters:
- location: str, {'main', 'sidebar'}, default 'main'
- Specifies the location of the register user widget.
- pre-authorization: bool, default True
- Specifies the pre-authorization requirement, True: user must be pre-authorized to register, False: any user can register.
- domains: list, default None
- Specifies the required list of domains a new email must belong to i.e. ['gmail.com', 'yahoo.com'], list: the required list of domains, None: any domain is allowed.
- fields: dict, default {'Form name':'Register user', 'Email':'Email', 'Username':'Username', 'Password':'Password', 'Repeat password':'Repeat password', 'Register':'Register'}
- Customizes the text of headers, buttons and other fields.
- clear_on_submit: bool, default False
- Specifies the clear on submit setting, True: clears inputs on submit, False: keeps inputs on submit.
Returns:
- str
- Email associated with the new user.
- str
- Username associated with the new user.
- str
- Name associated with the new user.
Please remember to update the config file (as shown in step 9) after you use this widget.
try:
username_of_forgotten_password, email_of_forgotten_password, new_random_password = authenticator.forgot_password()
if username_of_forgotten_password:
st.success('New password to be sent securely')
# The developer should securely transfer the new password to the user.
elif username_of_forgotten_password == False:
st.error('Username not found')
except Exception as e:
st.error(e)
Authenticate.forgot_password
Parameters
- location: str, {'main', 'sidebar'}, default 'main'
- Specifies the location of the forgot password widget.
- fields: dict, default {'Form name':'Forgot password', 'Username':'Username', 'Submit':'Submit'}
- Customizes the text of headers, buttons and other fields.
- clear_on_submit: bool, default False
- Specifies the clear on submit setting, True: clears inputs on submit, False: keeps inputs on submit.
Returns:
- str
- Username associated with the forgotten password.
- str
- Email associated with the forgotten password.
- str
- New plain text password that should be transferred to the user securely.
Please remember to update the config file (as shown in step 9) after you use this widget.
try:
username_of_forgotten_username, email_of_forgotten_username = authenticator.forgot_username()
if username_of_forgotten_username:
st.success('Username to be sent securely')
# The developer should securely transfer the username to the user.
elif username_of_forgotten_username == False:
st.error('Email not found')
except Exception as e:
st.error(e)
Authenticate.forgot_username
Parameters
- location: str, {'main', 'sidebar'}, default 'main'
- Specifies the location of the forgot username widget.
- fields: dict, default {'Form name':'Forgot username', 'Email':'Email', 'Submit':'Submit'}
- Customizes the text of headers, buttons and other fields.
- clear_on_submit: bool, default False
- Specifies the clear on submit setting, True: clears inputs on submit, False: keeps inputs on submit.
Returns:
- str
- Forgotten username that should be transferred to the user securely.
- str
- Email associated with the forgotten username.
if st.session_state["authentication_status"]:
try:
if authenticator.update_user_details(st.session_state["username"]):
st.success('Entries updated successfully')
except Exception as e:
st.error(e)
Authenticate.update_user_details
Parameters
- username: str
- Specifies the username of the user to update user details for.
- location: str, {'main', 'sidebar'}, default 'main'
- Specifies the location of the update user details widget.
- fields: dict, default {'Form name':'Update user details', 'Field':'Field', 'Name':'Name', 'Email':'Email', 'New value':'New value', 'Update':'Update'}
- Customizes the text of headers, buttons and other fields.
- clear_on_submit: bool, default False
- Specifies the clear on submit setting, True: clears inputs on submit, False: keeps inputs on submit.
Returns:
- bool
- Status of updating the user details.
Please remember to update the config file (as shown in step 9) after you use this widget.
with open('../config.yaml', 'w') as file:
yaml.dump(config, file, default_flow_style=False)