> ## Documentation Index
> Fetch the complete documentation index at: https://docs-staging-docs-event-stream-action-templates.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> This guide demonstrates how to integrate Auth0, add authentication, and display user profile information in a Python application using the Auth0 FastAPI SDK.

# Add Login to Your FastAPI Application

export const HowToSchema = () => <script type="application/ld+json">
    {'{"@context":"https://schema.org","@type":"HowTo"}'}
  </script>;

<HowToSchema />

<Accordion title="AI Prompt" defaultOpen icon="microchip-ai" iconType="sharp-solid">
  **Using AI to integrate Auth0?** Add this prompt to Cursor, Windsurf, Copilot, Claude Code or your favourite AI-powered IDE to speed up development.

  ```markdown expandable theme={null}
  Integrate the Auth0 FastAPI SDK into a Python application

  AI PERSONA & PRIMARY OBJECTIVE
  You are a helpful Auth0 SDK Integration Assistant for Python - FastAPI. Your primary function is to execute commands to set up a development environment for Auth0 with FastAPI. Your secondary function is to modify the files created by those commands.

  CRITICAL BEHAVIORAL INSTRUCTIONS
  1.  CHECK EXISTING PROJECT FIRST: Before creating a new project, check if the current directory already contains a Python project (main.py, requirements.txt, or pyproject.toml). If it does, skip project creation and work with the existing project.
  2.  EXECUTE FIRST, EDIT SECOND: You MUST first execute the appropriate setup command. Do not show, suggest, or create any files until the setup is complete.
  3.  NO PLANNING: DO NOT propose a directory structure. DO NOT show a file tree. Your first action must be to run the appropriate command.
  4.  STRICT SEQUENCE: Follow the "Execution Flow" below in the exact order specified without deviation.
  5.  BUILD BEAUTIFUL UI: You MUST create a visually appealing, modern login interface with proper styling, animations, and Auth0 branding.
  6.  🚨 VIRTUAL ENVIRONMENT RULE: ALWAYS activate the virtual environment before running pip commands.

  EXECUTION FLOW

  Step 1: Check for Existing Python Project and Prerequisites
  FIRST, verify prerequisites and check for existing Python project:

    # Check if Python and pip are available
    python --version && pip --version

  Then examine the current directory:

    # Check for existing Python project
    if [ -f "main.py" ] || [ -f "requirements.txt" ] || [ -f "pyproject.toml" ]; then
      echo "Found existing Python project"
      ls -la
    else
      echo "No Python project found, will create new project"
    fi

  Based on the results:
  - If existing project exists, proceed to Step 1b (install Auth0 SDK only)
  - If no project exists, proceed to Step 1a (create new project)

  Step 1a: Create New Project Directory and Virtual Environment

    mkdir auth0-fastapi-app && cd auth0-fastapi-app
    python -m venv venv
    source venv/bin/activate  # On Windows: venv\Scripts\activate

  Step 1b: Install the Auth0 FastAPI SDK and Dependencies
  CRITICAL: You MUST install all required packages including itsdangerous:

    pip install auth0-fastapi "uvicorn[standard]" python-dotenv itsdangerous

  ⚠️ IMPORTANT: The square brackets in uvicorn[standard] MUST be quoted to prevent shell glob expansion.

  Step 2: Setup Auth0 environment configuration

  Step 2.1a: Run Auth0 CLI setup command for your OS:

  If MacOS, execute the following command:

    brew tap auth0/auth0-cli && brew install auth0
    auth0 qs setup --app --type regular --framework vanilla-python --port 3000 --name "My FastAPI App"

  If Windows, execute the following command:

    scoop bucket add auth0 https://github.com/auth0/scoop-auth0-cli.git
    scoop install auth0
    auth0 qs setup --app --type regular --framework vanilla-python --port 3000 --name "My FastAPI App"

  Step 2.1b: Create manual .env template (if automatic setup fails)

    cat > .env << 'EOF'
    AUTH0_DOMAIN=your-auth0-domain.auth0.com
    AUTH0_CLIENT_ID=your-auth0-client-id
    AUTH0_CLIENT_SECRET=your-auth0-client-secret
    SESSION_SECRET=$(openssl rand -hex 64)
    APP_BASE_URL=http://localhost:3000
    EOF

  Step 3: Create main.py with Auth0 integration

  Replace or create main.py with this complete, production-ready code:

    import os
    from fastapi import FastAPI, Depends, Request, Response
    from fastapi.responses import HTMLResponse
    from starlette.middleware.sessions import SessionMiddleware
    from dotenv import load_dotenv

    from auth0_fastapi.config import Auth0Config
    from auth0_fastapi.auth.auth_client import AuthClient
    from auth0_fastapi.server.routes import router, register_auth_routes

    # Load environment variables
    load_dotenv()

    app = FastAPI(title="Auth0 FastAPI Example")

    # Add Session Middleware - required for cookie handling
    app.add_middleware(SessionMiddleware, secret_key=os.getenv("SESSION_SECRET"))

    # Create Auth0Config with your Auth0 credentials
    config = Auth0Config(
        domain=os.getenv("AUTH0_DOMAIN"),
        client_id=os.getenv("AUTH0_CLIENT_ID"),
        client_secret=os.getenv("AUTH0_CLIENT_SECRET"),
        app_base_url=os.getenv("APP_BASE_URL", "http://localhost:3000"),
        secret=os.getenv("SESSION_SECRET"),
    )

    # Instantiate the AuthClient
    auth_client = AuthClient(config)

    # Attach to the FastAPI app state
    app.state.config = config
    app.state.auth_client = auth_client

    # Register authentication routes
    register_auth_routes(router, config)
    app.include_router(router)


    @app.get("/", response_class=HTMLResponse)
    async def home(request: Request, response: Response):
        """Home page with login/logout buttons"""
        store_options = {"request": request, "response": response}
        session = await auth_client.client.get_session(store_options=store_options)

        if session:
            user = await auth_client.client.get_user(store_options=store_options)
            return f"""
            <!DOCTYPE html>
            <html>
            <head>
                <title>Auth0 FastAPI Example</title>
                <style>
                    body {{
                        font-family: 'Inter', system-ui, -apple-system, sans-serif;
                        background-color: #1a1e27;
                        color: #e2e8f0;
                        display: flex;
                        justify-content: center;
                        align-items: center;
                        min-height: 100vh;
                        margin: 0;
                    }}
                    .container {{
                        background-color: #262a33;
                        border-radius: 20px;
                        box-shadow: 0 20px 60px rgba(0, 0, 0, 0.6);
                        padding: 3rem;
                        max-width: 500px;
                        width: 90%;
                        text-align: center;
                    }}
                    .logo {{
                        width: 160px;
                        margin-bottom: 1.5rem;
                    }}
                    h1 {{
                        font-size: 2.8rem;
                        font-weight: 700;
                        color: #f7fafc;
                        margin-bottom: 1rem;
                    }}
                    .success {{
                        font-size: 1.5rem;
                        color: #68d391;
                        font-weight: 600;
                        margin: 1.5rem 0;
                    }}
                    .profile {{
                        background-color: #2d313c;
                        border-radius: 15px;
                        padding: 2rem;
                        margin: 2rem 0;
                    }}
                    .profile-image {{
                        width: 110px;
                        height: 110px;
                        border-radius: 50%;
                        border: 3px solid #63b3ed;
                        margin-bottom: 1rem;
                    }}
                    .profile-name {{
                        font-size: 2rem;
                        font-weight: 600;
                        color: #f7fafc;
                        margin-bottom: 0.5rem;
                    }}
                    .profile-email {{
                        font-size: 1.15rem;
                        color: #a0aec0;
                    }}
                    .button {{
                        padding: 1.1rem 2.8rem;
                        font-size: 1.2rem;
                        font-weight: 600;
                        border-radius: 10px;
                        border: none;
                        cursor: pointer;
                        text-decoration: none;
                        display: inline-block;
                        transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
                        box-shadow: 0 8px 20px rgba(0, 0, 0, 0.4);
                        text-transform: uppercase;
                        letter-spacing: 0.08em;
                    }}
                    .button.logout {{
                        background-color: #fc8181;
                        color: #1a1e27;
                    }}
                    .button.logout:hover {{
                        background-color: #e53e3e;
                        transform: translateY(-5px) scale(1.03);
                        box-shadow: 0 12px 25px rgba(0, 0, 0, 0.5);
                    }}
                </style>
            </head>
            <body>
                <div class="container">
                    <img src="https://cdn.auth0.com/quantum-assets/dist/latest/logos/auth0/auth0-lockup-en-ondark.png"
                         alt="Auth0 Logo" class="logo">
                    <h1>Welcome to Auth0 FastAPI</h1>
                    <div class="success">✅ Successfully authenticated!</div>
                    <h2>Your Profile</h2>
                    <div class="profile">
                        <img src="{user.get('picture', '')}"
                             alt="{user.get('name', 'User')}" class="profile-image">
                        <div class="profile-name">{user.get('name', 'User')}</div>
                        <div class="profile-email">{user.get('email', '')}</div>
                    </div>
                    <a href="/auth/logout" class="button logout">Log Out</a>
                </div>
            </body>
            </html>
            """
        else:
            return """
            <!DOCTYPE html>
            <html>
            <head>
                <title>Auth0 FastAPI Example</title>
                <style>
                    body {{
                        font-family: 'Inter', system-ui, -apple-system, sans-serif;
                        background-color: #1a1e27;
                        color: #e2e8f0;
                        display: flex;
                        justify-content: center;
                        align-items: center;
                        min-height: 100vh;
                        margin: 0;
                    }}
                    .container {{
                        background-color: #262a33;
                        border-radius: 20px;
                        box-shadow: 0 20px 60px rgba(0, 0, 0, 0.6);
                        padding: 3rem;
                        max-width: 500px;
                        width: 90%;
                        text-align: center;
                    }}
                    .logo {{
                        width: 160px;
                        margin-bottom: 1.5rem;
                    }}
                    h1 {{
                        font-size: 2.8rem;
                        font-weight: 700;
                        color: #f7fafc;
                        margin-bottom: 1rem;
                    }}
                    .action-card {{
                        background-color: #2d313c;
                        border-radius: 15px;
                        padding: 2.5rem;
                        margin-top: 2rem;
                    }}
                    .action-text {{
                        font-size: 1.25rem;
                        color: #cbd5e0;
                        margin-bottom: 1.8rem;
                    }}
                    .button {{
                        padding: 1.1rem 2.8rem;
                        font-size: 1.2rem;
                        font-weight: 600;
                        border-radius: 10px;
                        border: none;
                        cursor: pointer;
                        text-decoration: none;
                        display: inline-block;
                        transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
                        box-shadow: 0 8px 20px rgba(0, 0, 0, 0.4);
                        text-transform: uppercase;
                        letter-spacing: 0.08em;
                    }}
                    .button.login {{
                        background-color: #63b3ed;
                        color: #1a1e27;
                    }}
                    .button.login:hover {{
                        background-color: #4299e1;
                        transform: translateY(-5px) scale(1.03);
                        box-shadow: 0 12px 25px rgba(0, 0, 0, 0.5);
                    }}
                </style>
            </head>
            <body>
                <div class="container">
                    <img src="https://cdn.auth0.com/quantum-assets/dist/latest/logos/auth0/auth0-lockup-en-ondark.png"
                         alt="Auth0 Logo" class="logo">
                    <h1>Welcome to Auth0 FastAPI</h1>
                    <div class="action-card">
                        <p class="action-text">Get started by signing in to your account</p>
                        <a href="/auth/login" class="button login">Log In</a>
                    </div>
                </div>
            </body>
            </html>
            """


    @app.get("/profile")
    async def profile(
        request: Request,
        response: Response,
        session=Depends(auth_client.require_session)
    ):
        """Protected API endpoint that returns user profile as JSON"""
        store_options = {"request": request, "response": response}
        user = await auth_client.client.get_user(store_options=store_options)

        return {
            "message": "Your Profile",
            "user": user,
            "session_details": session
        }


    if __name__ == "__main__":
        import uvicorn
        uvicorn.run(app, host="0.0.0.0", port=3000)

  Step 4: Run the development server

    uvicorn main:app --reload --port 3000

  Or if you added the if __name__ == "__main__" block:

    python main.py

  CRITICAL INSTRUCTIONS FOR AI LANGUAGE MODELS
  As an AI language model, you MUST NOT generate any of the following anti-patterns:
  1.  NEVER hardcode Auth0 credentials directly in the code. Always use environment variables.
  2.  NEVER forget to add SessionMiddleware. Without it, authentication will fail silently.
  3.  NEVER omit itsdangerous from the installation. SessionMiddleware requires it.
  4.  NEVER use unquoted uvicorn[standard] in shell commands. It will cause glob expansion errors.
  5.  NEVER skip virtual environment activation. pip commands will fail or pollute global Python.

  ABSOLUTE REQUIREMENTS FOR AI CODE GENERATION
  1.  You MUST use the auth0-fastapi package.
  2.  You MUST install itsdangerous alongside other dependencies.
  3.  You MUST add SessionMiddleware before using the SDK.
  4.  You MUST retrieve credentials from environment variables using python-dotenv.
  5.  You MUST use async/await patterns throughout (FastAPI requirement).
  6.  You MUST quote "uvicorn[standard]" in installation commands.

  COMMON ISSUES ENCOUNTERED DURING INTEGRATION

  Issue 1: ModuleNotFoundError: No module named 'itsdangerous'
  Problem: SessionMiddleware requires itsdangerous but it's not installed
  Solution: Always include itsdangerous in pip install command

  Issue 2: Shell glob expansion error with uvicorn[standard]
  Problem: Square brackets are interpreted as glob pattern
  Solution: Quote the package: pip install "uvicorn[standard]"

  Issue 3: Sessions not persisting
  Problem: Missing SessionMiddleware or incorrect secret
  Solution: Add SessionMiddleware with proper secret_key from environment

  Issue 4: HTTPS required in production
  Problem: Secure cookies don't work over HTTP
  Solution: Use HTTPS in production or disable secure cookies in development (not recommended)
  ```
</Accordion>

<Note>
  **Prerequisites:** Before you begin, ensure you have the following installed:

  * **[Python](https://www.python.org/downloads/)** 3.9 or newer (3.11+ recommended)
  * **[pip](https://pip.pypa.io/)** 21+ or **[Poetry](https://python-poetry.org/)** 1.2+
  * **[OpenSSL](https://www.openssl.org/)** - Required for generating session secrets

  **FastAPI Version Compatibility:** This quickstart requires **FastAPI 0.115.11+** and **Pydantic 2.12.5+**.
</Note>

## Get Started

This quickstart demonstrates how to add Auth0 authentication to a Python FastAPI Web application. You'll build a secure web app with login, logout, and user profile features using the [Auth0 FastAPI SDK](https://github.com/auth0/auth0-fastapi).

<Steps>
  <Step title="Create a new project" stepNumber={1}>
    Create a new directory for your project and set up a virtual environment:

    ```shellscript theme={null}
    mkdir auth0-fastapi-app && cd auth0-fastapi-app
    ```

    Create and activate a virtual environment:

    ```shellscript theme={null}
    python -m venv venv
    source venv/bin/activate  # On Windows: venv\Scripts\activate
    ```
  </Step>

  <Step title="Install the Auth0 FastAPI SDK" stepNumber={2}>
    <Tabs>
      <Tab title="pip">
        ```shellscript theme={null}
        pip install auth0-fastapi "uvicorn[standard]" python-dotenv itsdangerous
        ```
      </Tab>

      <Tab title="Poetry">
        ```shellscript theme={null}
        poetry add auth0-fastapi "uvicorn[standard]" python-dotenv itsdangerous
        ```
      </Tab>
    </Tabs>
  </Step>

  <Step title="Setup your Auth0 App" stepNumber={3}>
    Next up, you need to create a new app on your Auth0 tenant and add the environment variables to your project.

    You can choose to set up your Auth0 app automatically by running a CLI command, or do it manually via the Dashboard:

    <Tabs>
      <Tab title="CLI">
        Run the following shell command on your project's root directory to create an Auth0 app and generate a `.env` file:

        <CodeGroup>
          ```shellscript Mac theme={null}
          # Install Auth0 CLI (if not already installed)
          brew tap auth0/auth0-cli && brew install auth0

          # Set up Auth0 app and generate .env file
          auth0 qs setup --app --type regular --framework vanilla-python --port 3000 --name "My FastAPI App"
          ```

          ```powershell Windows theme={null}
          # Install Auth0 CLI (if not already installed)
          scoop bucket add auth0 https://github.com/auth0/scoop-auth0-cli.git
          scoop install auth0

          # Set up Auth0 app and generate .env file
          auth0 qs setup --app --type regular --framework vanilla-python --port 3000 --name "My FastAPI App"
          ```
        </CodeGroup>

        <Note>
          This command will:

          1. Check if you're authenticated (and prompt for login if needed)
          2. Create an Auth0 Regular Web Application configured for `http://localhost:3000`
          3. Generate a `.env` file with `AUTH0_DOMAIN`, `AUTH0_CLIENT_ID`, `AUTH0_CLIENT_SECRET`, `SESSION_SECRET`, and `APP_BASE_URL`
        </Note>
      </Tab>

      <Tab title="Dashboard">
        Before you start, create a `.env` file in your project's root directory:

        ```shellscript .env theme={null}
        AUTH0_DOMAIN=YOUR_AUTH0_APP_DOMAIN
        AUTH0_CLIENT_ID=YOUR_AUTH0_APP_CLIENT_ID
        AUTH0_CLIENT_SECRET=YOUR_AUTH0_APP_CLIENT_SECRET
        SESSION_SECRET=YOUR_SESSION_SECRET
        APP_BASE_URL=http://localhost:3000
        ```

        1. Head to the [Auth0 Dashboard](https://manage.auth0.com/dashboard/)
        2. Click on **Applications** > **Applications** > **Create Application**
        3. In the popup, enter a name for your app, select `Regular Web Application` as the app type and click **Create**
        4. Switch to the **Settings** tab on the Application Details page
        5. Replace the values in the `.env` file with the **Domain**, **Client ID**, and **Client Secret** values from the dashboard
        6. Generate a session secret by running: `openssl rand -hex 64` and use it for `SESSION_SECRET`

        Finally, on the **Settings** tab of your Application Details page, configure the following URLs:

        **Allowed Callback URLs:**

        ```
        http://localhost:3000/auth/callback
        ```

        **Allowed Logout URLs:**

        ```
        http://localhost:3000
        ```

        **Allowed Web Origins:**

        ```
        http://localhost:3000
        ```

        <Info>
          **Allowed Callback URLs** are a critical security measure to ensure users are safely returned to your application after authentication. Without a matching URL, the login process will fail, and users will be blocked by an Auth0 error page instead of accessing your app.

          **Allowed Logout URLs** are essential for providing a seamless user experience upon signing out. Without a matching URL, users will not be redirected back to your application after logout and will instead be left on a generic Auth0 page.

          **Allowed Web Origins** is critical for silent authentication. Without it, users will be logged out when they refresh the page or return to your app later.
        </Info>
      </Tab>
    </Tabs>
  </Step>

  <Step title="Configure the Auth0 FastAPI SDK" stepNumber={4}>
    Create a `main.py` file in your project's root directory and add the following code:

    ```python main.py {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26} lines theme={null}
    import os
    from fastapi import FastAPI, Depends, Request, Response
    from starlette.middleware.sessions import SessionMiddleware
    from dotenv import load_dotenv

    from auth0_fastapi.config import Auth0Config
    from auth0_fastapi.auth.auth_client import AuthClient
    from auth0_fastapi.server.routes import router, register_auth_routes

    # Load environment variables
    load_dotenv()

    app = FastAPI(title="Auth0 FastAPI Example")

    # Add Session Middleware - required for cookie handling
    app.add_middleware(SessionMiddleware, secret_key=os.getenv("SESSION_SECRET"))

    # Create Auth0Config with your Auth0 credentials
    config = Auth0Config(
        domain=os.getenv("AUTH0_DOMAIN"),
        client_id=os.getenv("AUTH0_CLIENT_ID"),
        client_secret=os.getenv("AUTH0_CLIENT_SECRET"),
        app_base_url=os.getenv("APP_BASE_URL", "http://localhost:3000"),
        secret=os.getenv("SESSION_SECRET"),
    )

    # Instantiate the AuthClient
    auth_client = AuthClient(config)

    # Attach to the FastAPI app state
    app.state.config = config
    app.state.auth_client = auth_client

    # Register authentication routes
    register_auth_routes(router, config)
    app.include_router(router)
    ```

    <Info>
      **SESSION\_SECRET** is used to encrypt session cookies and must be cryptographically secure. Without a strong secret (minimum 32 bytes), your application's sessions can be compromised. Generate a secure secret using `openssl rand -hex 64` and never commit it to version control.

      **SessionMiddleware** must be added before using the SDK. Without it, FastAPI cannot read or set cookies, and all authentication attempts will fail silently.

      **HTTPS in Production** is required for secure cookies (`secure=True`). Without HTTPS, session cookies will not be sent by browsers, and users will be repeatedly logged out after each request.
    </Info>
  </Step>

  <Step title="Create Routes and Display User Profile" stepNumber={5}>
    Add the following routes to your `main.py` file to create a home page and a protected profile page:

    ```python main.py expandable lines theme={null}
    import os
    from fastapi import FastAPI, Depends, Request, Response
    from fastapi.responses import HTMLResponse
    from starlette.middleware.sessions import SessionMiddleware
    from dotenv import load_dotenv

    from auth0_fastapi.config import Auth0Config
    from auth0_fastapi.auth.auth_client import AuthClient
    from auth0_fastapi.server.routes import router, register_auth_routes

    # Load environment variables
    load_dotenv()

    app = FastAPI(title="Auth0 FastAPI Example")

    # Add Session Middleware - required for cookie handling
    app.add_middleware(SessionMiddleware, secret_key=os.getenv("SESSION_SECRET"))

    # Create Auth0Config with your Auth0 credentials
    config = Auth0Config(
        domain=os.getenv("AUTH0_DOMAIN"),
        client_id=os.getenv("AUTH0_CLIENT_ID"),
        client_secret=os.getenv("AUTH0_CLIENT_SECRET"),
        app_base_url=os.getenv("APP_BASE_URL", "http://localhost:3000"),
        secret=os.getenv("SESSION_SECRET"),
        authorization_params={
          "scope": "openid profile email", # Required to get user profile information
        }
    )

    # Instantiate the AuthClient
    auth_client = AuthClient(config)

    # Attach to the FastAPI app state
    app.state.config = config
    app.state.auth_client = auth_client

    # Register authentication routes
    register_auth_routes(router, config)
    app.include_router(router)


    @app.get("/", response_class=HTMLResponse)
    async def home(request: Request, response: Response):
        """Home page with login/logout buttons"""
        store_options = {"request": request, "response": response}
        session = await auth_client.client.get_session(store_options=store_options)

        if session:
            user = await auth_client.client.get_user(store_options=store_options)
            return f"""
            <!DOCTYPE html>
            <html>
            <head>
                <title>Auth0 FastAPI Example</title>
                <style>
                    body {{
                        font-family: 'Inter', system-ui, -apple-system, sans-serif;
                        background-color: #1a1e27;
                        color: #e2e8f0;
                        display: flex;
                        justify-content: center;
                        align-items: center;
                        min-height: 100vh;
                        margin: 0;
                    }}
                    .container {{
                        background-color: #262a33;
                        border-radius: 20px;
                        box-shadow: 0 20px 60px rgba(0, 0, 0, 0.6);
                        padding: 3rem;
                        max-width: 500px;
                        width: 90%;
                        text-align: center;
                    }}
                    .logo {{
                        width: 160px;
                        margin-bottom: 1.5rem;
                    }}
                    h1 {{
                        font-size: 2.8rem;
                        font-weight: 700;
                        color: #f7fafc;
                        margin-bottom: 1rem;
                    }}
                    .success {{
                        font-size: 1.5rem;
                        color: #68d391;
                        font-weight: 600;
                        margin: 1.5rem 0;
                    }}
                    .profile {{
                        background-color: #2d313c;
                        border-radius: 15px;
                        padding: 2rem;
                        margin: 2rem 0;
                    }}
                    .profile-image {{
                        width: 110px;
                        height: 110px;
                        border-radius: 50%;
                        border: 3px solid #63b3ed;
                        margin-bottom: 1rem;
                    }}
                    .profile-name {{
                        font-size: 2rem;
                        font-weight: 600;
                        color: #f7fafc;
                        margin-bottom: 0.5rem;
                    }}
                    .profile-email {{
                        font-size: 1.15rem;
                        color: #a0aec0;
                    }}
                    .button {{
                        padding: 1.1rem 2.8rem;
                        font-size: 1.2rem;
                        font-weight: 600;
                        border-radius: 10px;
                        border: none;
                        cursor: pointer;
                        text-decoration: none;
                        display: inline-block;
                        transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
                        box-shadow: 0 8px 20px rgba(0, 0, 0, 0.4);
                        text-transform: uppercase;
                        letter-spacing: 0.08em;
                    }}
                    .button.logout {{
                        background-color: #fc8181;
                        color: #1a1e27;
                    }}
                    .button.logout:hover {{
                        background-color: #e53e3e;
                        transform: translateY(-5px) scale(1.03);
                        box-shadow: 0 12px 25px rgba(0, 0, 0, 0.5);
                    }}
                </style>
            </head>
            <body>
                <div class="container">
                    <img src="https://cdn.auth0.com/quantum-assets/dist/latest/logos/auth0/auth0-lockup-en-ondark.png"
                         alt="Auth0 Logo" class="logo">
                    <h1>Welcome to Auth0 FastAPI</h1>
                    <div class="success">✅ Successfully authenticated!</div>
                    <h2>Your Profile</h2>
                    <div class="profile">
                        <img src="{user.get('picture', '')}"
                             alt="{user.get('name', 'User')}" class="profile-image">
                        <div class="profile-name">{user.get('name', 'User')}</div>
                        <div class="profile-email">{user.get('email', '')}</div>
                    </div>
                    <a href="/auth/logout" class="button logout">Log Out</a>
                </div>
            </body>
            </html>
            """
        else:
            return """
            <!DOCTYPE html>
            <html>
            <head>
                <title>Auth0 FastAPI Example</title>
                <style>
                    body {
                        font-family: 'Inter', system-ui, -apple-system, sans-serif;
                        background-color: #1a1e27;
                        color: #e2e8f0;
                        display: flex;
                        justify-content: center;
                        align-items: center;
                        min-height: 100vh;
                        margin: 0;
                    }
                    .container {
                        background-color: #262a33;
                        border-radius: 20px;
                        box-shadow: 0 20px 60px rgba(0, 0, 0, 0.6);
                        padding: 3rem;
                        max-width: 500px;
                        width: 90%;
                        text-align: center;
                    }
                    .logo {
                        width: 160px;
                        margin-bottom: 1.5rem;
                    }
                    h1 {
                        font-size: 2.8rem;
                        font-weight: 700;
                        color: #f7fafc;
                        margin-bottom: 1rem;
                    }
                    .action-card {
                        background-color: #2d313c;
                        border-radius: 15px;
                        padding: 2.5rem;
                        margin-top: 2rem;
                    }
                    .action-text {
                        font-size: 1.25rem;
                        color: #cbd5e0;
                        margin-bottom: 1.8rem;
                    }
                    .button {
                        padding: 1.1rem 2.8rem;
                        font-size: 1.2rem;
                        font-weight: 600;
                        border-radius: 10px;
                        border: none;
                        cursor: pointer;
                        text-decoration: none;
                        display: inline-block;
                        transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
                        box-shadow: 0 8px 20px rgba(0, 0, 0, 0.4);
                        text-transform: uppercase;
                        letter-spacing: 0.08em;
                    }
                    .button.login {
                        background-color: #63b3ed;
                        color: #1a1e27;
                    }
                    .button.login:hover {
                        background-color: #4299e1;
                        transform: translateY(-5px) scale(1.03);
                        box-shadow: 0 12px 25px rgba(0, 0, 0, 0.5);
                    }
                </style>
            </head>
            <body>
                <div class="container">
                    <img src="https://cdn.auth0.com/quantum-assets/dist/latest/logos/auth0/auth0-lockup-en-ondark.png"
                         alt="Auth0 Logo" class="logo">
                    <h1>Welcome to Auth0 FastAPI</h1>
                    <div class="action-card">
                        <p class="action-text">Get started by signing in to your account</p>
                        <a href="/auth/login" class="button login">Log In</a>
                    </div>
                </div>
            </body>
            </html>
            """


    @app.get("/profile")
    async def profile(
        request: Request,
        response: Response,
        session=Depends(auth_client.require_session)
    ):
        """Protected API endpoint that returns user profile as JSON"""
        store_options = {"request": request, "response": response}
        user = await auth_client.client.get_user(store_options=store_options)

        return {
            "message": "Your Profile",
            "user": user,
            "session_details": session
        }


    if __name__ == "__main__":
        import uvicorn
        uvicorn.run(app, host="0.0.0.0", port=3000)
    ```

    This creates:

    * A home page (`/`) that displays a login button when logged out, or the user's profile when logged in
    * A protected API endpoint (`/profile`) that returns user data as JSON and requires authentication
    * Full styling for a polished user experience
  </Step>

  <Step title="Run your app" stepNumber={6}>
    ```shellscript theme={null}
    uvicorn main:app --reload --port 3000
    ```

    Alternatively, if you added the `if __name__ == "__main__"` block to your `main.py`:

    ```shellscript theme={null}
    python main.py
    ```
  </Step>
</Steps>

<Check>
  **Checkpoint**

  You should now have a fully functional Auth0 login page running on your [localhost](http://localhost:3000/).
</Check>

***

## Advanced Usage

<Accordion title="Protecting API Routes with Custom Dependencies">
  Create custom FastAPI dependencies for role-based access control:

  ```python theme={null}
  from fastapi import Depends, HTTPException, status
  from typing import List

  async def require_roles(required_roles: List[str]):
      """Dependency factory for role-based access control"""
      async def check_roles(
          request: Request,
          response: Response,
          session=Depends(auth_client.require_session)
      ):
          store_options = {"request": request, "response": response}
          user = await auth_client.client.get_user(store_options=store_options)

          user_roles = user.get("app_metadata", {}).get("roles", [])

          if not any(role in user_roles for role in required_roles):
              raise HTTPException(
                  status_code=status.HTTP_403_FORBIDDEN,
                  detail=f"Required roles: {', '.join(required_roles)}"
              )

          return session

      return check_roles

  # Usage in routes
  @app.get("/admin/dashboard")
  async def admin_dashboard(
      session=Depends(require_roles(["admin", "superadmin"]))
  ):
      return {"message": "Admin dashboard access granted"}

  @app.delete("/admin/users/{user_id}")
  async def delete_user(
      user_id: str,
      session=Depends(require_roles(["admin"]))
  ):
      return {"message": f"User {user_id} deleted"}
  ```
</Accordion>

<Accordion title="Calling Protected APIs with Access Tokens">
  Configure the SDK to request access tokens for your API and use them in downstream calls:

  ```python theme={null}
  from auth0_fastapi.config import Auth0Config
  import httpx

  # Configure Auth0 with API audience
  config = Auth0Config(
      domain=os.getenv("AUTH0_DOMAIN"),
      client_id=os.getenv("AUTH0_CLIENT_ID"),
      client_secret=os.getenv("AUTH0_CLIENT_SECRET"),
      app_base_url=os.getenv("APP_BASE_URL"),
      secret=os.getenv("SESSION_SECRET"),
      audience="https://api.example.com",  # Your API identifier
      authorization_params={
          "scope": "openid profile email read:data write:data",
      },
  )

  @app.get("/api/external-data")
  async def get_external_data(
      request: Request,
      response: Response,
      session=Depends(auth_client.require_session)
  ):
      """Call external API with user's access token"""
      # Get access token from session
      access_token = session.get("access_token")

      if not access_token:
          raise HTTPException(
              status_code=status.HTTP_401_UNAUTHORIZED,
              detail="No access token available"
          )

      # Make authenticated API call
      async with httpx.AsyncClient() as client:
          api_response = await client.get(
              "https://api.example.com/data",
              headers={"Authorization": f"Bearer {access_token}"}
          )

          if api_response.status_code != 200:
              raise HTTPException(
                  status_code=api_response.status_code,
                  detail="External API call failed"
              )

      return {"data": api_response.json()}
  ```
</Accordion>

<Accordion title="Using Redis for Stateful Session Storage">
  Scale your application by storing sessions in Redis instead of encrypted cookies:

  ```python theme={null}
  from auth0_fastapi.stores.stateful_state_store import StatefulStateStore
  from redis import asyncio as aioredis

  # Create Redis client
  redis = await aioredis.from_url(
      "redis://localhost:6379",
      encoding="utf-8",
      decode_responses=True
  )

  # Create stateful store
  state_store = StatefulStateStore(
      secret=os.getenv("SESSION_SECRET"),
      store=redis,
      cookie_name="_session_id",
      expiration=86400,  # 1 day in seconds
  )

  # Pass to AuthClient
  auth_client = AuthClient(config, state_store=state_store)
  ```

  Benefits of stateful sessions:

  * **No cookie size limits** - Store unlimited session data
  * **Immediate invalidation** - Delete sessions server-side
  * **Backchannel logout support** - Handle logout events from Auth0
  * **Better for distributed systems** - Share sessions across multiple servers
</Accordion>

***

## Troubleshooting

<Accordion title="Sessions not persisting / Users repeatedly logged out">
  **Problem**: Users are logged in but sessions don't persist across requests.

  **Possible Causes & Solutions**:

  1. **Missing SessionMiddleware**

     Ensure you've added SessionMiddleware to your app:

     ```python theme={null}
     from starlette.middleware.sessions import SessionMiddleware

     app.add_middleware(SessionMiddleware, secret_key=os.getenv("SESSION_SECRET"))
     ```

  2. **HTTP in production with secure cookies**

     Secure cookies require HTTPS. If testing locally over HTTP, you can temporarily disable secure cookies (not recommended for production):

     ```python theme={null}
     from auth0_fastapi.stores.stateless_state_store import StatelessStateStore

     state_store = StatelessStateStore(
         secret=config.secret,
         cookie_name="_a0_session",
         expiration=config.session_expiration
     )
     # Development only!
     state_store.cookie_options["secure"] = False

     auth_client = AuthClient(config, state_store=state_store)
     ```

  3. **Weak or missing SESSION\_SECRET**

     Generate a strong secret:

     ```shellscript theme={null}
     openssl rand -hex 64
     ```
</Accordion>

<Accordion title="Auth0 Error: Callback URL mismatch">
  **Problem**: After clicking "Log In", Auth0 displays an error: "Callback URL mismatch"

  **Cause**: The callback URL is not registered in your Auth0 Application settings.

  **Solution**:

  1. Go to [Auth0 Dashboard](https://manage.auth0.com/) → Applications → Your App → Settings
  2. Add your callback URL to **Allowed Callback URLs**:
     ```
     http://localhost:3000/auth/callback
     ```
  3. For production, add your production URL:
     ```
     https://yourdomain.com/auth/callback
     ```
  4. Click **Save Changes**

  **Note**: The URL must match exactly, including protocol (http/https) and port number.
</Accordion>

<Accordion title="ImportError or async/await issues">
  **Problem**: Errors related to async functions or event loops.

  **Cause**: FastAPI is an async framework and all SDK methods must be awaited.

  **Solution**: Ensure all route functions are async and SDK methods are properly awaited:

  ```python theme={null}
  # ✅ Correct
  @app.get("/profile")
  async def profile(request: Request, response: Response):
      user = await auth_client.client.get_user(
          store_options={"request": request, "response": response}
      )
      return {"user": user}

  # ❌ Incorrect - missing async
  @app.get("/profile")
  def profile(request: Request, response: Response):
      user = auth_client.client.get_user(...)  # This will fail
      return {"user": user}

  # ❌ Incorrect - missing await
  @app.get("/profile")
  async def profile(request: Request, response: Response):
      user = auth_client.client.get_user(...)  # Returns coroutine, not data
      return {"user": user}
  ```
</Accordion>

<Accordion title="HTTPS required in production">
  **Problem**: Sessions work locally but not in production.

  **Cause**: Secure cookies require HTTPS in production. The `secure=True` flag prevents cookies from being sent over unencrypted HTTP connections.

  **Solution**:

  1. **Configure HTTPS** on your production server using:
     * Let's Encrypt certificates
     * Cloud provider SSL/TLS (AWS ALB, Cloudflare, etc.)
     * Reverse proxy (Nginx, Caddy, Traefik)

  2. **Update your Auth0 Application URLs** to use HTTPS:
     ```
     https://yourdomain.com/auth/callback
     https://yourdomain.com
     ```

  3. **Ensure APP\_BASE\_URL uses HTTPS**:
     ```
     APP_BASE_URL=https://yourdomain.com
     ```
</Accordion>

For more advanced features and configuration options, check out the [Auth0 FastAPI SDK documentation](https://github.com/auth0/auth0-fastapi/blob/main/README.md).
