I'm testing out a custom authentication component for my Streamlit app. However, when using the component in production, it fails to render for some reason.
I've managed to get i to work in dev mode by forking the code and adding it to my Streamlit project - but I still can't make it run in production.
Upon digging a bit, it seems to me that the declaration of the component fails since the build path for some reason doens't work. It looks like the assertion fails since the module is none as per the following traceback
venv\lib\site-packages\streamlit\components\v1\components.py:284, in declare_component(name, path, url)
281 # Get the caller's module name. `__name__` gives us the module's
282 # fully-qualified name, which includes its package.
283 module = inspect.getmodule(caller_frame)
--> 284 assert module is not None
...
288 # user executed `python my_component.py`), then this name will be
289 # "__main__" instead of the actual package name. In this case, we use
290 # the main module's filename, sans `.py` extension, as the component name.
AssertionError:
To obtain the build_path
I use the following:
root_dir = os.path.dirname(os.path.abspath(__file__))
build_dir = os.path.join(root_dir, "frontend" , "dist")
This returns:
'c:\\Users\\initials\\xxx\\Desktop\\Absence importer\\absense_importer\\frontend\\dist'
The component is declared like this:
_USE_WEB_DEV_SERVER = os.getenv("USE_WEB_DEV_SERVER", False)
_WEB_DEV_SERVER_URL = os.getenv("WEB_DEV_SERVER_URL", "http://localhost:5173")
COMPONENT_NAME = "msal_authentication"
root_dir = os.path.dirname(os.path.abspath(__file__))
build_dir = os.path.join(root_dir, "frontend" , "dist")
if _USE_WEB_DEV_SERVER:
_component_func = components.declare_component(name=COMPONENT_NAME, url=_WEB_DEV_SERVER_URL)
else:
_component_func = components.declare_component(name=COMPONENT_NAME, path=build_dir)
I've also tried to wrap everything inside a Linux Docker container, but to no avail, unfortunately. Can anyone spot my error?
I'm on Python 3.10.7 and using Streamlit 1.18.1.
EDIT:
Figured out my browswer has issues reading the compiled frontend code, due to a mismatch in MIME types. I'm not sure, what's wrong. By either adding the MIME types manually like
import mimetypes
mimetypes.add_type('application/javascript', '.js')
mimetypes.add_type('text/css', '.css')
Or using the sample-library from the author worked.
I am the author of said custom Streamlit Component, and I have made a small sample project that utilizes the component. I just ran the project in Docker, and it works for me. I have yet to discover what can cause the troubles on Windows.
Essentially, the sample project is just a barebone Streamlit dashboard consisting of the following script.
import streamlit as st
from msal_streamlit_authentication import msal_authentication
token_response = msal_authentication(
auth={
"clientId": "aaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee",
"authority": "https://login.microsoftonline.com/xxxxxxx-bbbb-cccc-dddd-eeeeeeeeeee",
"redirectUri": "/",
"postLogoutRedirectUri": "/"
},
cache={
"cacheLocation": "sessionStorage",
"storeAuthStateInCookie": False
},
login_request={
"scopes": ["yyyyyy-bbbb-cccc-dddd-eeeeeeeeeee/.default"]
},
key=1)
st.write("Received", token_response)
You should insert clientId, tenant/authority and scope values in accordance with your situation. Note that my test is based on the Authorization Code (PKCE) flow.