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

# PDF demo app

> FastAPI companion demo with streaming runs, parse_pdf, and local extraction

This tutorial follows the companion **PDF demo** application: a minimal chat UI that runs **`parse_pdf`** locally while the workflow executes over a **streaming** connection (no webhooks in the demo path). See [Getting started](/quickstart/getting-started) for the minimal API flow first. Install **`agentserviceapi`** from PyPI and import **`agentsapi`** to match this documentation.

## Prerequisites

* Python 3.10+
* An execution API **API key**
* The client library: **`pip install agentserviceapi`**, then **`from agentsapi import ...`** (or editable from your monorepo)
* Redis-backed SSE on the execution API side (required for interactive runs)

## 1. Clone and install

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
git clone <your-demo-repo-url>
cd <demo-repo>
python -m venv .venv
source .venv/bin/activate
pip install -e .
pip install agentserviceapi
```

## 2. Environment

Copy `.env.example` to `.env` and set at least your API key and base URL. Names vary by demo; common variables are listed in [Environment](/reference/environment).

## 3. One-time agent upload

The demo ships an orchestration JSON (for example `example_agent.json`). Upload it once so every developer shares the same graph:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
sudoiq-demo-upload example_agent.json
```

Equivalent: `python -m scripts.upload_orchestration example_agent.json`.

The command writes an **agent id** file (for example `.agent_id`) consumed by the app.

## 4. Run the server

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
uvicorn app.main:app --reload --host 0.0.0.0 --port 8080
```

Open `http://localhost:8080`, send a message, and attach a **PDF** when the workflow should call **`parse_pdf`**.

## 5. Request path (conceptual)

1. The browser posts chat input (and optional upload) to your FastAPI app.
2. The app builds local tool handlers (for example `build_local_tool_handlers` mapping **`parse_pdf`** to an async function).
3. It calls **`client.set_tools(...)`** then **`run_agent`** (or `execute_agent` and awaits the handle).
4. SSE delivers pauses for tools; the handler runs **`parse_pdf`** on the server using the uploaded file and returns JSON text.
5. The final **`AgentGraphRunStatusResponse`** is reduced to assistant text for the UI.

Inspect the demo source for exact module names after you align imports with **`agentsapi`**: typically `app/interactive_run.py`, `tools/parse_pdf.py`, and `app/main.py`.

## 6. Dump tool and validator JSON (optional)

If your tenant is missing **`parse_pdf`** or an invoice validator referenced by the graph, some demos ship a CLI to print registration payloads:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
sudoiq-demo-dump
# or: python -m app.dump_schemas
```

Flags often include `--tools`, `--validators`, and `-o combined.json`. Register the printed JSON in your product UI or automation.
