> ## Documentation Index
> Fetch the complete documentation index at: https://docs.timeback.com/llms.txt
> Use this file to discover all available pages before exploring further.

# FastAPI

> Integrate Timeback with FastAPI

## Overview

The Timeback Python SDK provides `TimebackFastAPI`, a ready-made FastAPI integration that creates an `APIRouter` with all Timeback routes.

## Installation

<CodeGroup>
  ```bash pip theme={null}
  pip install "timeback-sdk[fastapi]"
  ```

  ```bash uv theme={null}
  uv add "timeback-sdk[fastapi]"
  ```
</CodeGroup>

## Server Setup

### Timeback instance

Create a module that configures the Timeback instance. `TimebackFastAPI` is callable as a FastAPI dependency via `Depends(timeback)`:

<CodeGroup>
  ```python SSO (app/timeback.py) theme={null}
  import os

  from timeback.server import (
      TimebackConfig,
      ApiCredentials,
      SsoIdentityConfig,
  )
  from timeback.server.adapters.fastapi import TimebackFastAPI


  def get_user(request):
      session = get_session(request)  # Your session logic
      return {"id": session.user_id, "email": session.email}


  def on_callback_success(ctx):
      set_session(id=ctx.user["id"], email=ctx.user["email"])
      return ctx.redirect(ctx.state.get("return_to", "/"))


  def on_callback_error(ctx):
      return ctx.redirect("/?error=sso_failed")


  timeback = TimebackFastAPI(TimebackConfig(
      env="staging",
      api=ApiCredentials(
          client_id=os.environ["TIMEBACK_API_CLIENT_ID"],
          client_secret=os.environ["TIMEBACK_API_CLIENT_SECRET"],
      ),
      identity=SsoIdentityConfig(
          mode="sso",
          client_id=os.environ["TIMEBACK_SSO_CLIENT_ID"],
          client_secret=os.environ["TIMEBACK_SSO_CLIENT_SECRET"],
          redirect_uri="http://localhost:8000/api/timeback/identity/callback",
          get_user=get_user,
          on_callback_success=on_callback_success,
          on_callback_error=on_callback_error,
      ),
  ))
  ```

  ```python Custom Auth (app/timeback.py) theme={null}
  import os

  from timeback.server import (
      TimebackConfig,
      ApiCredentials,
      CustomIdentityConfig,
  )
  from timeback.server.adapters.fastapi import TimebackFastAPI


  def get_user_email(request):
      """Return the authenticated user's email from your auth system."""
      session_id = request.cookies.get("session_id")
      session = get_session(session_id)  # Your session logic
      return session.email if session else None


  timeback = TimebackFastAPI(TimebackConfig(
      env="staging",
      api=ApiCredentials(
          client_id=os.environ["TIMEBACK_API_CLIENT_ID"],
          client_secret=os.environ["TIMEBACK_API_CLIENT_SECRET"],
      ),
      identity=CustomIdentityConfig(
          mode="custom",
          get_email=get_user_email,
      ),
  ))
  ```
</CodeGroup>

### App initialization

Mount the Timeback router on your FastAPI app:

```python app/main.py theme={null}
from fastapi import FastAPI

from app.timeback import timeback

app = FastAPI()
app.include_router(timeback.router, prefix="/api/timeback")
```

No lifespan or async setup needed — `TimebackFastAPI` is fully initialized at construction time.

## Usage

Use `Depends(timeback)` in your own routes for server-side operations like recording activity completion or fetching user data:

```python app/routes/activities.py theme={null}
from fastapi import APIRouter, Depends
from timeback.server import TimebackInstance

from app.timeback import timeback

router = APIRouter(prefix="/api/activities")


@router.put("/{activity_id}/complete")
async def complete_activity(
    activity_id: str,
    tb: TimebackInstance = Depends(timeback),
):
    activity = await load_activity(activity_id)
    progress = await load_progress(activity_id)

    await tb.activity.record({
        "user": {"email": progress.student_email},
        "activity": {
            "id": activity.slug,
            "name": activity.name,
            "course": {"code": activity.course_code},
        },
        "metrics": {
            "xp_earned": progress.xp_earned,
            "total_questions": progress.total_questions,
            "correct_questions": progress.correct_questions,
        },
        "run_id": progress.run_id,
    })

    return {"status": "completed"}
```

You can also use the `timeback.user` namespace to verify users or fetch profiles without going through the HTTP handlers:

```python app/routes/users.py theme={null}
from fastapi import APIRouter, Depends
from timeback.server import TimebackInstance

from app.timeback import timeback

router = APIRouter(prefix="/api/users")


@router.get("/check/{email}")
async def check_user(
    email: str,
    tb: TimebackInstance = Depends(timeback),
):
    result = await tb.user.verify(email)
    return result


@router.get("/profile/{email}")
async def get_profile(
    email: str,
    tb: TimebackInstance = Depends(timeback),
):
    profile = await tb.user.get_profile(email)
    return profile
```

<Note>
  See [stateful activities](/beta/build-on-timeback/sdk/activity-tracking/stateful) for the full
  server-side completion workflow, and [user profile](/beta/build-on-timeback/sdk/user-profile)
  for details on `verify()` and `get_profile()`.
</Note>

The lessons namespace is also available via `Depends(timeback)`:

```python app/routes/lessons.py theme={null}
from fastapi import APIRouter, Depends
from timeback.server import TimebackInstance

from app.timeback import timeback

router = APIRouter(prefix="/api/lessons")


@router.get("/")
async def list_lessons(tb: TimebackInstance = Depends(timeback)):
    return await tb.lessons.list()


@router.post("/{lesson_id}/start")
async def start_lesson(
    lesson_id: str,
    student_id: str,
    tb: TimebackInstance = Depends(timeback),
):
    return await tb.lessons.start({"student": student_id, "lesson": lesson_id})
```

<Note>
  See the [Managed Lessons reference](/beta/build-on-timeback/sdk/managed-lessons/reference#server)
  for all server-side operations (`list`, `start`, `next`, `submit`, `complete`, `attempts`, `attemptDetails`),
  parameters, and return types.
</Note>

## Next Steps

<CardGroup cols={2}>
  <Card title="Managed Lessons" href="/beta/build-on-timeback/sdk/managed-lessons/reference#server">
    Server-side lessons API reference
  </Card>

  <Card title="Custom Activities" href="/beta/build-on-timeback/sdk/activity-tracking/intro">
    Track learning sessions
  </Card>

  <Card title="Client Adapters" href="/beta/build-on-timeback/sdk/overview">
    Frontend setup (React, Vue, Svelte, Solid)
  </Card>

  <Card title="Identity" href="/beta/build-on-timeback/sdk/identity">
    Authentication options
  </Card>
</CardGroup>
