|
| 1 | +# Lab 0: Set up from a team card |
| 2 | + |
| 3 | +**Cloud course** · 5 minutes, plus 5 on your own · CLI, Python, or TypeScript |
| 4 | + |
| 5 | +You put your team card in `.env`, load the login stream into your team's Kafka |
| 6 | +cluster, and run the doctor. When this lab is done, the Agent Engine, Kafka, |
| 7 | +and Schema Registry on your card all answer, and your topic holds 246 logins. |
| 8 | + |
| 9 | +No team card? [Lab 0: Set up](00-set-up.md) starts from an instance of your own |
| 10 | +instead. Both end in the same place, and Lab 1 is the same after either. |
| 11 | + |
| 12 | +## Before you start |
| 13 | + |
| 14 | +- You have your **team card** from the organizers: an **API key**, and the |
| 15 | + addresses of the environment they created for your team on StreamNative |
| 16 | + Cloud. That environment is a Kafka cluster, a SQL workspace that imports it, |
| 17 | + an agent workspace, and the service account the key belongs to. Everything on |
| 18 | + the card already exists: you create nothing, and you do not need `snctl`. |
| 19 | +- You can log in to StreamNative Cloud, and the organizers added your login to |
| 20 | + your team's environment. This lab does not use that login; Labs 2 and 3 do. |
| 21 | +- You cloned this repository and opened a terminal in it. The terminal runs |
| 22 | + `bash`: on Windows that is WSL or Git Bash, on every path, because the checks |
| 23 | + are `bash` commands. |
| 24 | +- You have `git`, [`ork`](https://github.com/orca-ae/orca-cli) v0.6.0 or newer, |
| 25 | + and [`jq`](https://jqlang.org/download/). `ork` does the first MCP login in |
| 26 | + Lab 3 for all three paths, and `ork` with `jq` runs the checks in every lab. |
| 27 | + |
| 28 | +## Step 1: Install your path |
| 29 | + |
| 30 | +Pick **one** path. Your teammate can pick a different one. |
| 31 | + |
| 32 | +**Python** (3.11 or newer) |
| 33 | + |
| 34 | +```bash |
| 35 | +cd python |
| 36 | +python3 -m venv .venv |
| 37 | +source .venv/bin/activate # Git Bash on Windows: source .venv/Scripts/activate |
| 38 | +pip install -r requirements.txt |
| 39 | +``` |
| 40 | + |
| 41 | +**TypeScript** (Node.js 20 or newer) |
| 42 | + |
| 43 | +```bash |
| 44 | +cd typescript |
| 45 | +npm install |
| 46 | +``` |
| 47 | + |
| 48 | +**CLI**: `ork` and `jq` are all the labs need. Set up Python or TypeScript as |
| 49 | +above too: the doctor, the seeder, and the data injector come from one of them. |
| 50 | + |
| 51 | +### Check |
| 52 | + |
| 53 | +Run the doctor without the network. Every line says `PASS`. |
| 54 | + |
| 55 | +| Python or CLI | TypeScript | |
| 56 | +|---|---| |
| 57 | +| `python doctor.py --offline` | `npm run doctor -- --offline` | |
| 58 | + |
| 59 | +```text |
| 60 | +PASS Python 3.11+ 3.13 |
| 61 | +PASS package runorca |
| 62 | +PASS package confluent-kafka[avro] |
| 63 | +PASS package python-dotenv |
| 64 | +PASS ork found |
| 65 | +PASS jq found |
| 66 | +
|
| 67 | +All good: you're ready. |
| 68 | +``` |
| 69 | + |
| 70 | +## Step 2: Fill in `.env` from your team card |
| 71 | + |
| 72 | +Open a second terminal at the repository root and copy the template: |
| 73 | + |
| 74 | +```bash |
| 75 | +cp .env.cloud.example .env |
| 76 | +``` |
| 77 | + |
| 78 | +`.env` is git-ignored. It will hold your team's key: do not commit it or paste |
| 79 | +it anywhere. Give each of these lines its value from the card: |
| 80 | + |
| 81 | +| `.env` line | On your card | Write it as | |
| 82 | +|---|---|---| |
| 83 | +| `SN_API_KEY` | API key | the raw key, with no `token:` in front | |
| 84 | +| `SN_SERVICE_ACCOUNT` | Service account | `<name>@<org>.auth.streamnative.cloud`. If the card has only the name, add the rest, with the organization id from the card (`o-...`) | |
| 85 | +| `ORCA_BASE_URL` | Agent workspace endpoint | `https://` and the host, with no `/v1` | |
| 86 | +| `KAFKA_BOOTSTRAP_SERVERS` | Broker URL | the host and its port, `:9093` | |
| 87 | +| `SCHEMA_REGISTRY_URL` | Schema registry URL | `https://` and the host | |
| 88 | +| `SN_MCP_URL` | SQL workspace MCP endpoint | `https://mcp.streamnative.cloud/mcp/x/<org>/sqlworkspace.compute.streamnative.io/<SQL workspace>` | |
| 89 | +| `SN_SQL_DATABASE` | SQL database | as given. It is the name of your SQL catalog, not of your SQL workspace | |
| 90 | + |
| 91 | +If your card already is a list of `NAME=value` lines, paste each one over the |
| 92 | +empty line with the same name. |
| 93 | + |
| 94 | +`SN_SQL_DATABASE` is the database you use in Lab 2 and the agent targets in |
| 95 | +Labs 3 and 4. Leave the other lines as they are: the MCP server uses a separate |
| 96 | +browser login in Lab 3, so `SN_MCP_AUTH=oauth` stays, and `SN_MCP_OAUTH_ISSUER` |
| 97 | +stays empty. |
| 98 | + |
| 99 | +**Two people share one team card.** Your teammate fills in the same values, and |
| 100 | +you both work in the same Kafka cluster and the same SQL database. Your agents |
| 101 | +stay apart: each is named after its owner's OS user name, like |
| 102 | +`hello-agent-ana`. If the two of you have the same user name, each set |
| 103 | +`PARTICIPANT` in `.env` to a name of your own. In Lab 2 the view and the table |
| 104 | +are created once for the team: if your teammate got there first, the `CREATE` |
| 105 | +statement says they already exist, and you go on to the step's check. The reset |
| 106 | +script that Lab 4 mentions drops them for both of you, so agree before one of |
| 107 | +you runs it. |
| 108 | + |
| 109 | +### Check |
| 110 | + |
| 111 | +One authenticated read of your Agent Engine. It prints `true` when the endpoint |
| 112 | +and the key on your card are accepted. |
| 113 | + |
| 114 | +```bash |
| 115 | +./lab-ork agent list -o json | jq -e 'has("data")' |
| 116 | +``` |
| 117 | + |
| 118 | +Before you filled in `.env`, the same command says |
| 119 | +`Missing ORCA_BASE_URL, SN_API_KEY` instead: the two values it needs. |
| 120 | + |
| 121 | +## Step 3: Load the login stream |
| 122 | + |
| 123 | +The course reads one topic in your team's Kafka cluster, |
| 124 | +`security.login_events`. It needs the login stream once, for the whole team. |
| 125 | +**One of you** runs the seeder, in your path's folder: |
| 126 | + |
| 127 | +| Python | TypeScript | CLI | |
| 128 | +|---|---|---| |
| 129 | +| `python seed.py` | `npm run seed` | `(cd ../python && .venv/bin/python seed.py)` or `(cd ../typescript && npm run seed)` | |
| 130 | + |
| 131 | +It prints one of two lines, and both are fine. A topic that was empty is now |
| 132 | +loaded: |
| 133 | + |
| 134 | +```text |
| 135 | +Loaded 246 logins for 91 accounts into security.login_events. |
| 136 | +``` |
| 137 | + |
| 138 | +A topic that the organizers or your teammate loaded before you is left as it is: |
| 139 | + |
| 140 | +```text |
| 141 | +security.login_events already holds 246 events, so it is seeded. To load another copy anyway: python seed.py --force |
| 142 | +``` |
| 143 | + |
| 144 | +Do not use `--force`: a second copy would double every count in Lab 2. The |
| 145 | +number is higher than 246 once someone on your team has run Lab 3, and the |
| 146 | +TypeScript seeder ends the line with `npm run seed -- --force`. |
| 147 | + |
| 148 | +The seeder replays [`data/login_events.jsonl`](../../data/login_events.jsonl): |
| 149 | +synthetic logins at a fictional bank, with their timestamps moved to now. It |
| 150 | +also registers the topic's Avro schema, which SQL Workspace needs in Lab 2. |
| 151 | + |
| 152 | +If it says `The topic security.login_events does not exist yet`, the topic was |
| 153 | +not created with your environment. Raise your hand, or create it yourself with |
| 154 | +`snctl`: [Lab 0: Set up](00-set-up.md), step 3. |
| 155 | + |
| 156 | +### Check |
| 157 | + |
| 158 | +Run the doctor. It checks your laptop, then each service on your card, and a |
| 159 | +failed check prints its fix on the next line. |
| 160 | + |
| 161 | +| Python | TypeScript | CLI | |
| 162 | +|---|---|---| |
| 163 | +| `python doctor.py` | `npm run doctor` | `(cd ../python && .venv/bin/python doctor.py)` or `(cd ../typescript && npm run doctor)` | |
| 164 | + |
| 165 | +After the lines from step 1, it prints: |
| 166 | + |
| 167 | +```text |
| 168 | +PASS .env cloud stack, participant: ana |
| 169 | +PASS ORCA_BASE_URL https://... |
| 170 | +PASS Agent Engine API key accepted |
| 171 | +PASS Kafka security.login_events has 1 partition(s) |
| 172 | +PASS Schema Registry security.login_events-value v1 |
| 173 | +PASS login topic schema has account_id, event_time, ip_address, result, failure_reason |
| 174 | +WAIT MCP OAuth no tutorial vault yet |
| 175 | + next: Nothing to do now: Lab 3 opens your browser to authorize the MCP server. Run doctor again after it. |
| 176 | +
|
| 177 | +You're ready. 1 check(s) wait for a later lab. |
| 178 | +``` |
| 179 | + |
| 180 | +`WAIT` is not a failure. The MCP server needs a login that only Lab 3 can do. |
| 181 | +On a topic that nobody has loaded yet, the `Schema Registry` line fails before |
| 182 | +this step: the seeder is what registers the schema. |
| 183 | + |
| 184 | +Still failing after two tries? Raise your hand, or see |
| 185 | +[Troubleshooting](troubleshooting.md). |
| 186 | + |
| 187 | +## Check your understanding |
| 188 | + |
| 189 | +**1. The doctor prints `WAIT MCP OAuth`. What should you do?** |
| 190 | + |
| 191 | +- A. Fix it now: the doctor has to print only `PASS`. |
| 192 | +- B. Nothing yet: Lab 3 does the browser login this check waits for. |
| 193 | +- C. Ask for a new team card. |
| 194 | + |
| 195 | +<details> |
| 196 | +<summary>Answer</summary> |
| 197 | + |
| 198 | +**B.** The MCP server wants an OAuth login, and the lab script does it the first |
| 199 | +time the agent needs the server. `WAIT` means "not ready, and not your mistake". |
| 200 | +A real problem prints `FAIL` and its fix. |
| 201 | + |
| 202 | +</details> |
| 203 | + |
| 204 | +**2. The seeder says `security.login_events already holds 246 events, so it is seeded`. What should you do?** |
| 205 | + |
| 206 | +- A. Run it again with `--force`, so that your copy is loaded too. |
| 207 | +- B. Nothing: the stream is there already, loaded by the organizers or by your teammate. |
| 208 | +- C. Ask for a new Kafka cluster. |
| 209 | + |
| 210 | +<details> |
| 211 | +<summary>Answer</summary> |
| 212 | + |
| 213 | +**B.** Your team shares one topic, and it needs the 246 logins once. A second |
| 214 | +copy would double every count in Lab 2. |
| 215 | + |
| 216 | +</details> |
| 217 | + |
| 218 | +**3. What does `./lab-ork` add to `ork`?** |
| 219 | + |
| 220 | +- A. It is a different CLI with its own commands. |
| 221 | +- B. It points `ork` at your Agent Engine with the key from `.env`, and fills in the ids your scripts saved. |
| 222 | +- C. It runs the lab's steps for you. |
| 223 | + |
| 224 | +<details> |
| 225 | +<summary>Answer</summary> |
| 226 | + |
| 227 | +**B.** Everything after `./lab-ork` goes to `ork` as you typed it. The wrapper |
| 228 | +only supplies the endpoint, the credential, and the four `@..._id` words. |
| 229 | + |
| 230 | +</details> |
| 231 | + |
| 232 | +## Try it yourself |
| 233 | + |
| 234 | +Make the doctor fail on purpose, so you know what a failure looks like before a |
| 235 | +real one. Change one value in `.env` so that a check fails, read the fix the |
| 236 | +doctor prints, then put the value back. |
| 237 | + |
| 238 | +### Check |
| 239 | + |
| 240 | +The doctor ends on the "ready" line again. |
| 241 | + |
| 242 | +```bash |
| 243 | +(cd python && .venv/bin/python doctor.py) | tail -n 1 |
| 244 | +``` |
| 245 | + |
| 246 | +On the TypeScript path, use `npm --prefix typescript run doctor | tail -n 1`. |
| 247 | + |
| 248 | +<details> |
| 249 | +<summary>Solution</summary> |
| 250 | + |
| 251 | +Add `/v1` to the end of `ORCA_BASE_URL` and run the doctor: |
| 252 | + |
| 253 | +```text |
| 254 | +FAIL ORCA_BASE_URL https://<your-host>/v1 |
| 255 | + fix: Use the host root only: ORCA_BASE_URL=https://<your-host> |
| 256 | +``` |
| 257 | + |
| 258 | +The doctor does not call an endpoint it can see is wrong. It skips the Agent |
| 259 | +Engine check, tells you the exact value to use, and ends with |
| 260 | +`1 check(s) failed`. Remove the `/v1` and run it again. |
| 261 | + |
| 262 | +</details> |
| 263 | + |
| 264 | +## Recap |
| 265 | + |
| 266 | +- `.env` holds your team card: the addresses of your team's environment and its |
| 267 | + key. It is git-ignored. |
| 268 | +- Your team shares that environment. The login stream is loaded once, and the |
| 269 | + seeder refuses a second copy. |
| 270 | +- The doctor checks each service on the card and prints the fix for a failure. |
| 271 | +- `./lab-ork` is how you look at your Agent Engine from the terminal. |
| 272 | + |
| 273 | +## What's next |
| 274 | + |
| 275 | +[Lab 1: Hello, agent](01-hello-agent.md) |
0 commit comments