0

I am working on a webapp which has these:

FastAPI - Backend Chainlit - Frontend

The chainlit frontend is mounted on the FastAPI backend. He is how it looks in the code:

@app.get("/")
async def redirect_to_chainlit():
    return RedirectResponse(url="/chainlit")

def mount_static_files(directory, path):
    if os.path.exists(directory):
        app.mount(path, StaticFiles(directory=directory), name=f"{directory}-static")

# mounting data and tool
os.makedirs("data", exist_ok=True)
mount_static_files("data", "/api/files/data")
app.include_router(chat_router, prefix="/api/chat")

# Mounting frontend
ROOT_DIR = Path(__file__).resolve().parent.parent
FRONTEND_DIR = os.path.join(ROOT_DIR, "frontend")
FRONTEND_PUBLIC_DIR = os.path.join(FRONTEND_DIR, "public")
FRONTEND_APP_PATH = os.path.join(FRONTEND_DIR, "app", "app.py")

if os.path.exists(FRONTEND_PUBLIC_DIR):
    app.mount(
        "/chainlit/public",
        StaticFiles(directory=FRONTEND_PUBLIC_DIR),
        name="chainlit-static"
    )
    logger.info(f"Mounted Chainlit static files from: {FRONTEND_PUBLIC_DIR}")
else:
    logger.error(f'Cannot mount Chainlit - directory does not exist: {FRONTEND_PUBLIC_DIR}')

if os.path.exists(FRONTEND_APP_PATH):
    mount_chainlit(app=app, target=FRONTEND_APP_PATH, path="/chainlit")
    logger.info(f"Mounted Chainlit app from: {FRONTEND_APP_PATH}")
else:
    logger.error(f'Cannot mount Chainlit app - file does not exist: {FRONTEND_APP_PATH}')

if __name__ == "__main__":
    app_host = os.getenv("APP_HOST", "0.0.0.0")
    app_port = int(os.getenv("PORT", "8080"))

    reload_dirs = [dir for dir in os.listdir() if dir != "data"]
    reload = False
    uvicorn.run(
        app="backend.main:app",
        host=app_host,
        port=app_port,
        reload=reload,
        reload_dirs=reload_dirs,
        timeout_keep_alive=120,
        timeout_graceful_shutdown=60
    )

I have multiple routes:

  • upload-files
  • extract
  • submit-feedback

here are the routes in app/api/routers/chat.py:

chat_router = r = APIRouter()

@r.post("/submit-feedback")
async def save_feedback(
    request: Request,
    feedback: dict = Body(...),
)-> FileUploadResponse:

@r.post("/upload-files")
async def upload_files(
    request: Request,
    files: list[UploadFile] = File(...)
) -> FileUploadResponse:

@r.post("/extract")
async def extract_request(
    request: Request,
    extract_req: ExtractRequest,
    program: MultiModalLLMCompletionProgram = Depends(get_multi_model_extractor),
) -> InfoMessage:

The app does not perform any logins, instead the logins are taken care of by azure as there is an identity configured for authentication, here is how it looks like:

enter image description here

enter image description here

I need to access the user id in frontend and in backend. I need becasue users can uplaod files so they have their own dirs to store files. Also, when they send feedback, I want the feedback data to have the user id. Also, in frontend (chainlit) I load user files to view from user directory (i.e data/<user-identitufer-number/id>) so I need the userid in both front and backend.

I have tried using:

  • headers: but it gives 401 not authorized even if I send access token in the headers
  • singleSignIn: 401 not authorized

I tried with the headers:

@router.post("/upload-files")
async def upload_files(request: Request, files: list[UploadFile] = File(...)):
    user_id = request.headers.get("X-MS-CLIENT-PRINCIPAL-ID")

It just gives 401 not authorized all the time.

I have also tried sending the token:

def get_token():
    client_id=os.getenv("APP_REG_CLIENT_ID", None)
    client_credential=os.getenv("APP_REG_CLIENT_SECRET", None),
    tenant_id=os.getenv('APP_REG_TENANT_ID', None)
    if client_id and client_credential and tenant_id:
        app = msal.ConfidentialClientApplication(
            client_id=client_id,
            client_credential=client_credential,
            authority=f"https://login.microsoftonline.com/{tenant_id}"
        )

        result = app.acquire_token_for_client(scopes=["https://management.azure.com/.default"])
        print(result)
        access_token = result["access_token"]
        return access_token
    else:
        raise Exception("Environment variables for Azure App Registration are not set correctly.")

headers = {"Authorization": f"Bearer {get_token()}"}
    response = await async_api_call(
        method="GET",
        endpoint="/api/chat/user-info",
        timeout=600.0,
        headers=headers
    )
    if isinstance(response, httpx.Response):
        try:
            return response.json()['user_id']
        except (ValueError, KeyError) as e:
            raise Exception("Invalid response structure") from e
    else:
        raise Exception(response.get("message", "Unknown error"))

but again 401 not authorized.

I just need the simples way possible to get the user id both during local run and on the webapp.

Can someone help please, I have been stuck for 2 days now and chatgpt is a just crap!

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.