Streamlit Authenticate.__init__() 获得参数“cookie_expiry_days”的多个值

Tim*_*ess 2 python visual-studio-code streamlit

我正在构建一个基本的 Streamlit 应用程序。为了验证用户凭据,我使用了Streamlit身份验证模块。只有一个问题,代码不起作用!

错误

类型错误:验证。init () 获得参数 'cookie_expiry_days' 的多个值

追溯:

文件“C:\Users_M92\Desktop\Coding\Python\Projects\Personal1\venv\lib\site-packages\streamlit\scriptrunner\script_runner.py”,第 557 行,在 _run_script exec(code, module.dict )

文件“app.py”,第 23 行,authenticator = stauth.Authenticate(names, usernames, hashed_pa​​sswords,

顺便说一句,我使用了官方文档中描述的相同代码:

代码

import streamlit as st
import streamlit_authenticator as stauth

names = ['John Smith', 'Rebecca Briggs']
usernames = ['jsmith', 'rbriggs']
passwords = ['123', '456']

hashed_passwords = stauth.Hasher(passwords).generate()

authenticator = stauth.Authenticate(names, usernames, hashed_passwords,
    'some_cookie_name', 'some_signature_key', cookie_expiry_days=30)

name, authentication_status, username = authenticator.login('Login', 'main')

if authentication_status:
    authenticator.logout('Logout', 'main')
    st.write('Welcome *%s*' % (name))
    st.title('Some content')
elif authentication_status == False:
    st.error('Username/password is incorrect')
elif authentication_status == None:
    st.warning('Please enter your username and password')

if st.session_state['authentication_status']:
    st.write('Welcome *%s*' % (st.session_state['name']))
    st.title('Some content')
elif st.session_state['authentication_status'] == False:
    st.error('Username/password is incorrect')
elif st.session_state['authentication_status'] == None:
    st.warning('Please enter your username and password')
Run Code Online (Sandbox Code Playgroud)

当我删除参数时cookie_expiry_days=30,我收到此错误:

类型错误:列表索引必须是整数或切片,而不是 str

文件“C:\Users_M92\Desktop\Coding\Python\Projects\Personal1\venv\lib\site-packages\streamlit_authenticator\authenticate.py”,第 36 行,在 __init__self.credentials['usernames'] = {key.lower( ): 键的值,凭证中的值['usernames'].items()}

您知道为什么我不断收到这些错误吗?

Cee*_*far 6

所以两天后,OP 仍然没有回复:p 这是我在检查 0.2.1 后发现的内容,正如 ferdy 指出的......

新格式需要凭证字典,给出的示例如下

credentials:   
 usernames:
    jsmith:
      email: jsmith@gmail.com
      name: John Smith
      password: '123' # To be replaced with hashed password
    rbriggs:
      email: rbriggs@gmail.com
      name: Rebecca Briggs
      password: '456' # To be replaced with hashed password 
 cookie:   expiry_days: 30   
 key: some_signature_key   
 name: some_cookie_name 
 preauthorized:   emails:
   - melsby@gmail.com
Run Code Online (Sandbox Code Playgroud)

但由于它需要一个 yaml,而且我基本上都是用旧的方式设置的(基于 Coding is Fun 的youtube教程),我想直接将凭据传递给身份验证器,所以如果您的原始代码是这样的......

authenticator = stauth.Authenticate(names, usernames, passwords, "app_home", "auth", cookie_expiry_days=30)
Run Code Online (Sandbox Code Playgroud)

你想要的是这样的字典

    credentials = {
        "usernames":{
            usernames[0]:{
                "name":names[0],
                "password":passwords[0]
                },
            usernames[1]:{
                "name":names[1],
                "password":passwords[1]
                }            
            }
        }
Run Code Online (Sandbox Code Playgroud)

然后你将其传递给验证器,就像这样......

authenticator = stauth.Authenticate(credentials, "app_home", "auth", cookie_expiry_days=30)
Run Code Online (Sandbox Code Playgroud)

所以只是为了澄清你生成的凭证字典看起来像这样......

    credentials = {
        "usernames":{
            "jsmith92":{
                "name":"john smith",
                "password":"$2b$12$TSuKwWML0EpbohBQgHx4p8E5q"
                },
            "tturner":{
                "name":"timmy turner",
                "password":"$2b$12$asdaUduuibuEIyBUBHASD896a"
                }            
            }
        }
Run Code Online (Sandbox Code Playgroud)

正如您可能注意到的,我没有将 cookie 部分包含在字典中(因为他们声明您应该在 config.yaml 中),但它仍然可以正常工作

当然,现在您可以根据每个列表中有多少项(名称、密码、用户名)在循环中填写这些变量,但如果您只想快速测试一组或两组凭据,这是一种快速而简单的方法这样做。

这里供参考的是我用来根据用户、名称和密码列表中的任意数量的凭据动态创建最终凭据字典的循环...

credentials = {"usernames":{}}

for un, name, pw in zip(usernames, names, passwords):
    user_dict = {"name":name,"password":pw}
    credentials["usernames"].update({un:user_dict})

authenticator = stauth.Authenticate(credentials, "app_home", "auth", cookie_expiry_days=30)
Run Code Online (Sandbox Code Playgroud)

首先使用用户名键和空字典作为值初始化凭证字典。

然后将凭据(用户名、姓名、密码)压缩在一起并循环它们。注意我的示例 - un 表示用户名,pw 表示密码

然后,我们使用更新函数将每个 user_dict 作为“usernames”键下的值添加到凭据字典中。注意 - 请务必将字典包装在更新部分的 {} 中,即 .update({un:user_dict})

您可能还想在用户验证后添加一个注销按钮,因为一旦用户通过身份验证(30 天 cookie),登录表单就会消失,因此如果您没有登录表单,则几乎无法进行测试。

您可以通过一个简单的 if 语句来做到这一点,使用之前的authentication_status,如下所示......

if authentication_status == True:
    authenticator.logout("logout","main")
Run Code Online (Sandbox Code Playgroud)

抱歉,它很长,但我认为 id 更新包括我使用的实际循环,这是我使用的正在工作的代码,对于任何想要它的人来说都是完整的

    # my class function which makes a call to a database and returns a list of lists (nested list), of usernames, names, and passwords
    users = usr.get_all_users_credentials()
    # the code mentioned above
    usernames = [user[1] for user in users]
    names = [user[2] for user in users]
    passwords = [user[3] for user in users]

    credentials = {"usernames":{}}

    for un, name, pw in zip(usernames, names, passwords):
        user_dict = {"name":name,"password":pw}
        credentials["usernames"].update({un:user_dict})

    authenticator = stauth.Authenticate(credentials, "app_home", "auth", cookie_expiry_days=30)

    name, authentication_status, username = authenticator.login("Login", "main")

    if authentication_status == True:
        authenticator.logout("logout","main")
Run Code Online (Sandbox Code Playgroud)