streamlit-passwordless
======================
|PyPI| |conda-forge| |conda-forge-platform| |Python| |LICENSE|
streamlit-passwordless provides a user model for Streamlit applications based on the Bitwarden
passwordless.dev technology. It allows users to securely authenticate with a Streamlit application
using passkeys. The project is under development and not ready for production yet.
A demo of the project is available at: https://passwordless.streamlit.app
Installation
------------
streamlit-passwordless is available on `PyPI`_ and `conda-forge`_ and can be installed with `pip`_
or `conda`_.
.. _conda: https://docs.conda.io/en/latest/
.. _conda-forge: https://anaconda.org/conda-forge/streamlit_passwordless
.. _pip: https://pip.pypa.io/en/stable/getting-started/
.. _PyPI: https://pypi.org/project/streamlit-passwordless/
Install with pip:
.. code-block:: bash
$ pip install streamlit-passwordless
Install with conda:
.. code-block:: bash
$ conda install conda-forge::streamlit_passwordless
License
-------
streamlit-passwordless is distributed under the `MIT-license`_.
.. _MIT-license: https://opensource.org/licenses/mit-license.php
Example
-------
Let's create an example Streamlit app using streamlit-passwordless. First create an account with
`Bitwarden Passwordless.dev`_ and make your *public* and *private* key accessible to your
application. This can be accomplished through environment variables or the `Streamlit secrets`_.
Create a new virtual environment and install streamlit-passwordless.
.. _Bitwarden Passwordless.dev: https://admin.passwordless.dev/Account/Login
.. _python-dotenv: https://pypi.org/project/python-dotenv/
.. _Streamlit secrets: https://docs.streamlit.io/develop/api-reference/connections/secrets.toml
.. code-block:: bash
~ $ mkdir stp_demo && cd stp_demo
~/stp_demo $ python -m venv .venv
~/stp_demo $ source .venv/bin/activate
~/stp_demo (.venv) $ python -m pip install streamlit-passwordless
~/stp_demo (.venv) $ mkdir .streamlit && touch .streamlit/secrets.toml
On Windows you should replace with ``source .venv/bin/activate`` with ``.venv/bin/Activate.ps1``.
The contents of the file *~/stp_demo/.streamlit/secrets.toml* is shown below. Replace ``<PUBLIC_KEY>``
and ``<PRIVATE_KEY>`` with your actual *public* and *private* key from Bitwarden Passwordless.dev. The
*private key* is called *secret key* in Bitwarden Passwordless.dev. Alternatively you can set the
environment variables `STP_BWP_PUBLIC_KEY` and `STP_BWP_PRIVATE_KEY` to the values of the *public*
and *private* keys respectively.
.. code-block:: toml
[streamlit-passwordless]
STP_BWP_PUBLIC_KEY = '<PUBLIC_KEY>'
STP_BWP_PRIVATE_KEY = '<PRIVATE_KEY>'
Copy the code of the example app below into a file called *app.py* and place it in your
working directory *stp_demo*.
.. code-block:: python
# app.py
import streamlit as st
import streamlit_passwordless as stp
def main() -> None:
r"""The main function to run the app."""
page_title = 'Streamlit Passwordless Minimal Example'
st.set_page_config(page_title=page_title)
st.title(page_title)
client, session_factory, _ = stp.setup(create_database=True)
with session_factory() as session:
stp.db.init(_session=session)
register_tab, signin_in_tab = st.tabs(['Register', 'Sign in'])
with register_tab:
stp.bitwarden_register_form(client=client, db_session=session)
with signin_in_tab:
stp.bitwarden_sign_in_form(client=client, db_session=session)
stp.sign_out_button(use_container_width=True)
if __name__ == '__main__':
main()
The ``stp.setup`` function initializes the session state variables needed by streamlit-passwordless,
loads and validates the configuration, creates the ``client`` for communicating with Bitwarden
Passwordless.dev and finally creates the ``session_factory`` for interacting with the user database.
By setting ``create_database=True`` the tables of the database are created. By default a SQLite
database (*streamlit_passwordless.db*) located in the current working directory is used. The database
to use can be specified through the config key or environment variable ``STP_DB_URL``, which takes a
`SQLAlchemy database URL`_.
The function ``stp.db.init`` initializes the database by creating the default user roles. This function
is cached with st.cache_resource_, which makes it only execute once. The database can also be initialized
through the streamlit-passwordless CLI by running the command ``stp run init``. It launches a Streamlit
app that initializes the database and lets you create an admin user for the application. Lastly the forms
to *register* and *sign in* are rendered in separate tabs, and finally the *sign out* button is rendered.
.. _st.cache_resource : https://docs.streamlit.io/develop/api-reference/caching-and-state/st.cache_resource
.. _SQLAlchemy database URL : https://docs.sqlalchemy.org/en/20/core/engines.html#database-urls
Run the example app with the following command:
.. code-block:: bash
~/stp_demo (.venv) $ python -m streamlit run app.py
You can now view your Streamlit app in your browser.
Local URL: http://localhost:8501
Open the url in your favorite web browser and try it out!
.. |conda-forge| image:: https://img.shields.io/conda/vn/conda-forge/streamlit_passwordless?style=plastic
:alt: conda-forge - Version
:target: https://anaconda.org/conda-forge/streamlit_passwordless
.. |conda-forge-platform| image:: https://img.shields.io/conda/pn/conda-forge/streamlit_passwordless?color=yellowgreen&style=plastic
:alt: conda-forge - Platform
:target: https://anaconda.org/conda-forge/streamlit_passwordless
.. |LICENSE| image:: https://img.shields.io/pypi/l/streamlit-passwordless?style=plastic
:alt: PyPI - License
:target: https://github.com/antonlydell/streamlit-passwordless/blob/main/LICENSE
.. |PyPI| image:: https://img.shields.io/pypi/v/streamlit-passwordless?style=plastic
:alt: PyPI
:target: https://pypi.org/project/streamlit-passwordless/
.. |Python| image:: https://img.shields.io/pypi/pyversions/streamlit-passwordless?style=plastic
:alt: PyPI - Python Version
:target: https://pypi.org/project/streamlit-passwordless/
Raw data
{
"_id": null,
"home_page": null,
"name": "streamlit-passwordless",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.11",
"maintainer_email": null,
"keywords": "Bitwarden, FIDO2, Passkey, Passwordless, Streamlit, Web, WebAuthn",
"author": null,
"author_email": "Anton Lydell <anton.thedev@tuta.com>",
"download_url": "https://files.pythonhosted.org/packages/55/d6/953970d92d0036b37f66df14cc585c17899cfa9a6588deb1e0f78bb645e7/streamlit_passwordless-0.17.0.tar.gz",
"platform": null,
"description": "streamlit-passwordless\n======================\n\n|PyPI| |conda-forge| |conda-forge-platform| |Python| |LICENSE|\n\n\nstreamlit-passwordless provides a user model for Streamlit applications based on the Bitwarden\npasswordless.dev technology. It allows users to securely authenticate with a Streamlit application\nusing passkeys. The project is under development and not ready for production yet.\n\nA demo of the project is available at: https://passwordless.streamlit.app\n\n\nInstallation\n------------\n\nstreamlit-passwordless is available on `PyPI`_ and `conda-forge`_ and can be installed with `pip`_\nor `conda`_.\n\n.. _conda: https://docs.conda.io/en/latest/\n.. _conda-forge: https://anaconda.org/conda-forge/streamlit_passwordless\n.. _pip: https://pip.pypa.io/en/stable/getting-started/\n.. _PyPI: https://pypi.org/project/streamlit-passwordless/\n\n\nInstall with pip:\n\n.. code-block:: bash\n\n $ pip install streamlit-passwordless\n\n\nInstall with conda:\n\n.. code-block:: bash\n\n $ conda install conda-forge::streamlit_passwordless\n\n\nLicense\n-------\n\nstreamlit-passwordless is distributed under the `MIT-license`_.\n\n.. _MIT-license: https://opensource.org/licenses/mit-license.php\n\n\nExample\n-------\n\nLet's create an example Streamlit app using streamlit-passwordless. First create an account with\n`Bitwarden Passwordless.dev`_ and make your *public* and *private* key accessible to your\napplication. This can be accomplished through environment variables or the `Streamlit secrets`_.\nCreate a new virtual environment and install streamlit-passwordless.\n\n.. _Bitwarden Passwordless.dev: https://admin.passwordless.dev/Account/Login\n.. _python-dotenv: https://pypi.org/project/python-dotenv/\n.. _Streamlit secrets: https://docs.streamlit.io/develop/api-reference/connections/secrets.toml\n\n\n.. code-block:: bash\n\n ~ $ mkdir stp_demo && cd stp_demo\n ~/stp_demo $ python -m venv .venv\n ~/stp_demo $ source .venv/bin/activate\n ~/stp_demo (.venv) $ python -m pip install streamlit-passwordless\n ~/stp_demo (.venv) $ mkdir .streamlit && touch .streamlit/secrets.toml\n\n\nOn Windows you should replace with ``source .venv/bin/activate`` with ``.venv/bin/Activate.ps1``.\nThe contents of the file *~/stp_demo/.streamlit/secrets.toml* is shown below. Replace ``<PUBLIC_KEY>``\nand ``<PRIVATE_KEY>`` with your actual *public* and *private* key from Bitwarden Passwordless.dev. The\n*private key* is called *secret key* in Bitwarden Passwordless.dev. Alternatively you can set the\nenvironment variables `STP_BWP_PUBLIC_KEY` and `STP_BWP_PRIVATE_KEY` to the values of the *public*\nand *private* keys respectively.\n\n\n.. code-block:: toml\n\n [streamlit-passwordless]\n STP_BWP_PUBLIC_KEY = '<PUBLIC_KEY>'\n STP_BWP_PRIVATE_KEY = '<PRIVATE_KEY>'\n\n\nCopy the code of the example app below into a file called *app.py* and place it in your\nworking directory *stp_demo*.\n\n\n.. code-block:: python\n\n # app.py\n\n\n import streamlit as st\n import streamlit_passwordless as stp\n\n\n def main() -> None:\n r\"\"\"The main function to run the app.\"\"\"\n\n page_title = 'Streamlit Passwordless Minimal Example'\n st.set_page_config(page_title=page_title)\n st.title(page_title)\n\n client, session_factory, _ = stp.setup(create_database=True)\n with session_factory() as session:\n stp.db.init(_session=session)\n register_tab, signin_in_tab = st.tabs(['Register', 'Sign in'])\n with register_tab:\n stp.bitwarden_register_form(client=client, db_session=session)\n with signin_in_tab:\n stp.bitwarden_sign_in_form(client=client, db_session=session)\n\n stp.sign_out_button(use_container_width=True)\n\n\n if __name__ == '__main__':\n main()\n\n\nThe ``stp.setup`` function initializes the session state variables needed by streamlit-passwordless,\nloads and validates the configuration, creates the ``client`` for communicating with Bitwarden\nPasswordless.dev and finally creates the ``session_factory`` for interacting with the user database.\nBy setting ``create_database=True`` the tables of the database are created. By default a SQLite\ndatabase (*streamlit_passwordless.db*) located in the current working directory is used. The database\nto use can be specified through the config key or environment variable ``STP_DB_URL``, which takes a\n`SQLAlchemy database URL`_.\n\nThe function ``stp.db.init`` initializes the database by creating the default user roles. This function\nis cached with st.cache_resource_, which makes it only execute once. The database can also be initialized\nthrough the streamlit-passwordless CLI by running the command ``stp run init``. It launches a Streamlit\napp that initializes the database and lets you create an admin user for the application. Lastly the forms\nto *register* and *sign in* are rendered in separate tabs, and finally the *sign out* button is rendered.\n\n.. _st.cache_resource : https://docs.streamlit.io/develop/api-reference/caching-and-state/st.cache_resource\n.. _SQLAlchemy database URL : https://docs.sqlalchemy.org/en/20/core/engines.html#database-urls\n\n\nRun the example app with the following command:\n\n.. code-block:: bash\n\n ~/stp_demo (.venv) $ python -m streamlit run app.py\n\n You can now view your Streamlit app in your browser.\n\n Local URL: http://localhost:8501\n\n\nOpen the url in your favorite web browser and try it out!\n\n\n.. |conda-forge| image:: https://img.shields.io/conda/vn/conda-forge/streamlit_passwordless?style=plastic\n :alt: conda-forge - Version\n :target: https://anaconda.org/conda-forge/streamlit_passwordless\n\n\n.. |conda-forge-platform| image:: https://img.shields.io/conda/pn/conda-forge/streamlit_passwordless?color=yellowgreen&style=plastic\n :alt: conda-forge - Platform\n :target: https://anaconda.org/conda-forge/streamlit_passwordless\n\n\n.. |LICENSE| image:: https://img.shields.io/pypi/l/streamlit-passwordless?style=plastic\n :alt: PyPI - License\n :target: https://github.com/antonlydell/streamlit-passwordless/blob/main/LICENSE\n\n\n.. |PyPI| image:: https://img.shields.io/pypi/v/streamlit-passwordless?style=plastic\n :alt: PyPI\n :target: https://pypi.org/project/streamlit-passwordless/\n\n\n.. |Python| image:: https://img.shields.io/pypi/pyversions/streamlit-passwordless?style=plastic\n :alt: PyPI - Python Version\n :target: https://pypi.org/project/streamlit-passwordless/\n",
"bugtrack_url": null,
"license": null,
"summary": "A user model for Streamlit applications based on passwordless technology.",
"version": "0.17.0",
"project_urls": {
"Bug Tracker": "https://github.com/antonlydell/streamlit-passwordless/issues",
"Documentation": "https://github.com/antonlydell/streamlit-passwordless",
"Source Code": "https://github.com/antonlydell/streamlit-passwordless"
},
"split_keywords": [
"bitwarden",
" fido2",
" passkey",
" passwordless",
" streamlit",
" web",
" webauthn"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "510da34c7679cf0234db5761b0dd4bc64090967bf5eb9de670f649ca87674038",
"md5": "1fae42bfc27df5f4cc4b72d89b6e2293",
"sha256": "44fdb3f70097a7055182f897dccb4250f00e13bc8bb79c507d30ea37f1304929"
},
"downloads": -1,
"filename": "streamlit_passwordless-0.17.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "1fae42bfc27df5f4cc4b72d89b6e2293",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.11",
"size": 213074,
"upload_time": "2025-10-11T17:43:57",
"upload_time_iso_8601": "2025-10-11T17:43:57.085311Z",
"url": "https://files.pythonhosted.org/packages/51/0d/a34c7679cf0234db5761b0dd4bc64090967bf5eb9de670f649ca87674038/streamlit_passwordless-0.17.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "55d6953970d92d0036b37f66df14cc585c17899cfa9a6588deb1e0f78bb645e7",
"md5": "2147df0a90c0ea7a39b425bcee42f858",
"sha256": "3b4b42f67a231f7f54a203bf590764ba3279a9d2ca73e8f92364cc98017cab96"
},
"downloads": -1,
"filename": "streamlit_passwordless-0.17.0.tar.gz",
"has_sig": false,
"md5_digest": "2147df0a90c0ea7a39b425bcee42f858",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.11",
"size": 192218,
"upload_time": "2025-10-11T17:44:00",
"upload_time_iso_8601": "2025-10-11T17:44:00.697403Z",
"url": "https://files.pythonhosted.org/packages/55/d6/953970d92d0036b37f66df14cc585c17899cfa9a6588deb1e0f78bb645e7/streamlit_passwordless-0.17.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-10-11 17:44:00",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "antonlydell",
"github_project": "streamlit-passwordless",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "streamlit-passwordless"
}