User Sessions

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 access and decode 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)