Accessing user session information in apps
For apps deployed to organizations or shared through subscriptions, it can be
useful for the app to know which user is accessing the app at a certain time.
This is information is accessible on the cookie numerous_user_info
added to
requests that arrive on the app server.
The cookie content is a base64 encoded JSON object, with the public user ID and
the user's name added. For example, if a user has the ID abcdefghij1234567890
,
and the full name Jane Doe
, then the JSON object would look like:
{
"user_id": "abcdefghij1234567890",
"user_full_name": "Jane Doe"
}
Which when base64 encoded, would look like:
ewogICAgInVzZXJfaWQiOiAiYWJjZGVmZ2hpajEyMzQ1Njc4OTAiLAogICAgInVzZXJfZnVsbF9uYW1lIjogIkphbmUgRG9lIgp9
User session functionality is still on an experimental stage. More customized implementations for accessing user session information are on their way.
For example, in a Streamlit app, the user information can be accessed like below:
import base64
import json
import streamlit as st
user_info_cookie = st.context.cookies["numerous_user_info"]
user_info = json.loads(base64.b64decode(user_info_cookie))
st.write(f"User ID: {user_info['user_id']}")
st.write(f"Full Name: {user_info['user_full_name']}")
Accessing user session information in Marimo apps
Marimo does not officially support a mechanism to access cookies from the requests generated by user interaction on the running app. To still allow Marimo developers to use the Numerous user session information, we have developed an experimental feature in the Numerous SDK (opens in a new tab), that enables access to cookies related to the correct session.
In the notebook code, import the function numerous.experimental.marimo.cookies
,
which returns available cookies as a dictionary, and accesses and decodes the user
session information.
import base64
import json
import numerous.experimental.marimo
cookies = numerous.experimental.marimo.cookies()["numerous_user_info"]
user_info = json.loads(base64.b64decode(user_info))
user_id = user_info["user_id"]
full_name = user_info["user_full_name"]
In order for this functionality to work, the Marimo notebook has to be run through a Marimo CLI wrapper, or the Marimo app has to be run as a FastAPI app and special middleware has to be added.
Run Marimo through the CLI wrapper
To run the Marimo notebook with the wrapper, the marimo command can be prepended
with the python -m numerous
, e.g.
python -m numerous marimo run app.py
Be careful not to confuse running the Python Numerous SDK module with python -m numerous
with running the Numerous CLI, which is just numerous
.
In order to run the app with the wrapper when it is deployed, it must be deployed
with a Dockerfile
. See how to deploy apps with Dockerfiles
here.
FROM python:3.11-slim
EXPOSE 8000
WORKDIR /app
COPY . .
RUN pip install -r requirements.txt
ENTRYPOINT [ "python", "-m", "numerous", "marimo", "run", "notebook.py",
"--host=0.0.0.0", "--port=8000" ]
Run Marimo with cookie middleware
Using the ability to run the Marimo backend programmatically (opens in a new tab) we can add a middleware that ensures that cookies are accessible for each user session.
import marimo
from fastapi import FastAPI
from numerous.experimental.marimo import add_marimo_cookie_middleware
server = marimo.create_asgi_app().with_app(path="", root="app.py")
app = FastAPI()
app.mount("/", server.build())
# add the cookie middleware
add_marimo_cookie_middleware(app)
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)