Reference card: commands, ports, status codes and terms
Course home · Learning map · Glossary · Submission evidence
Look it up here; learn it where it is taught. Each row restates one line from a lecture or guide and links to it, so open the link whenever a row is not enough. This card adds no rule, command or date of its own: the course guide remains the authority for requirements and deadlines.
On this page
Product map and ports
Your product has three application services. Requests go from the browser to the frontend, to the backend, to the AI service; only the backend touches the database (product requirements).
| Service | Built with | Port | Calls | Taught in |
|---|---|---|---|---|
| Frontend | Streamlit, React or another web framework | 8501 | the backend only | Lecture 4 |
| Backend | FastAPI and Pydantic | 8000 | the database, and the AI service over HTTP | Lecture 2 · Lecture 7 |
| AI service | FastAPI and Pydantic AI | 8001 | a model, through its provider (TestModel in tests) | Lecture 6 |
| Database | a SQLite file on a Docker volume (PostgreSQL is allowed) | none | nothing: only the backend opens it | Lecture 3 |
Every container has its own localhost, so the right address depends on where the caller runs:
| Caller | Reaches | Address | Taught in |
|---|---|---|---|
| Your browser | the frontend | http://localhost:8501 | Lecture 4 |
Your terminal (curl, /docs) | the backend | http://localhost:8000 | Lecture 2 |
| The backend, run by hand | the AI service | http://localhost:8001 | Lecture 7 |
| The frontend’s Python (Streamlit), under Compose | the backend | http://backend:8000 | Lecture 8 |
| A React app (it runs in your browser), under Compose | the backend | http://localhost:8000 plus CORS, or the proxy in Lecture 8’s optional box | Lecture 8 |
| The backend, under Compose | the AI service | http://ai-service:8001 | Lecture 8 |
| Your laptop, under Compose | the AI service | nothing: the AI service has no ports: | Lecture 8 |
Commands by task
Run each uv command from the service’s own folder: uv run uses the nearest pyproject.toml, so the folder decides the project (Lecture 1).
Run and test one service
| Task | Command | Run it from | Taught in |
|---|---|---|---|
| Start the backend | uv run fastapi dev | backend/ | Lecture 2 |
| Start the AI service | uv run fastapi dev --port 8001 | ai-service/ | Lecture 7 |
| Start the frontend | uv run streamlit run streamlit_app.py | frontend/ | Lecture 4 |
| Check that the backend answers | curl http://localhost:8000/health | any folder; expect {"status":"ok"} | Lecture 1 |
| Run the service’s tests | uv run pytest | the service’s folder | Lecture 2 |
| Run the browser test | uv run pytest e2e --base-url http://localhost:8501 | frontend/, with the backend and frontend running | Lecture 5 |
| Lint, then check formatting | uv run ruff check ., then uv run ruff format --check . | the service’s folder | Lecture 2 |
| Fix formatting | uv run ruff format . | the service’s folder | Lecture 4 |
Add a package (test tools with --dev) | uv add "fastapi[standard]", uv add --dev pytest | the service’s folder | Lecture 1 · Lecture 2 |
Run the whole stack
Run every docker compose command from the repository root, where compose.yaml lives.
| Task | Command | Taught in |
|---|---|---|
| Build, start everything and stream the logs (Ctrl+C stops) | docker compose up --build | Lecture 8 |
| Start in the background and wait until every service is healthy | docker compose up --build --wait | Lecture 8 |
| See each service’s health and ports | docker compose ps | Lecture 8 |
| Follow one service’s logs | docker compose logs -f backend | Lecture 8 |
| Open a shell inside a running container | docker compose exec backend sh | Lecture 8 |
Stop one service (start brings it back) | docker compose stop ai-service | Lecture 8 |
| Remove the containers and the network, and keep your data | docker compose down | Lecture 8 |
| Also delete the volumes, including your data | docker compose down -v | Lecture 8 |
| Validate the file without printing it | docker compose config --quiet | Lecture 8 |
Git every day
The habit: read git diff --staged before every commit, especially when an assistant wrote the change.
| Task | Command | Taught in |
|---|---|---|
| See which files changed and where each change lives | git status | Lecture 1 |
| See edits you have not staged yet | git diff | Lecture 1 |
| See exactly what the next commit records | git diff --staged | Lecture 1 |
| Stage a file | git add <file> | Lecture 1 |
| Commit what you staged, with a message saying why | git commit -m "Add product sketch" | Lecture 1 |
| Start a branch | git switch -c add-product-sketch | Lecture 1 |
| Push a new branch to GitHub | git push -u origin add-product-sketch | Lecture 1 |
| Open a PR on your own repository | gh pr create --fill | Lecture 1 |
| Merge it as one commit and delete the branch | gh pr merge --squash --delete-branch | Lecture 1 |
| Bring the merge to your laptop | git switch main, then git pull | Lecture 1 |
| List your local commits | git log --oneline | Lecture 1 |
| List the PRs merged on GitHub | gh pr list --state merged | Lecture 1 |
Undo a Git mistake
Pick the undo by where the mistake lives.
| I want to | Safe command | Careful | Taught in |
|---|---|---|---|
| Throw away an edit I have not staged | git restore <file> | the edit is gone for good: Git never stored it | Undo safely |
| Unstage a file but keep the edit | git restore --staged <file> | nothing is lost | Undo safely |
| Fix the last commit’s message before pushing | git commit --amend -m "Better message" | do not amend commits you already pushed | Undo safely |
| Undo a commit that is already pushed | git revert <sha> | safe on shared branches: a new commit reverses the old one | Undo safely |
| Abandon an experiment branch | git switch main, then git branch -D try-x | unmerged work disappears from view | Undo safely |
| Get out of a merge I do not understand | git merge --abort | works only while the merge is unfinished | Undo safely |
Watch out: never rewrite pushed main. If a bad commit reached GitHub, git revert it and push the new commit.
Pull requests and evidence with gh
| Task | Command | Taught in |
|---|---|---|
| Check your product repository’s owner | gh repo view --json nameWithOwner,url | Lecture 1 |
| Save a candidate’s stars, license and fork status on the day you open the PR | gh repo view OWNER/REPO --json stargazerCount,licenseInfo,pushedAt,isFork | Lecture 3 |
| Fork the project and clone your fork | gh repo fork OWNER/REPO --clone | Lecture 3 |
| Open the upstream PR in the browser | gh pr create --web | Lecture 3 |
| List your open PRs | gh search prs --author=@me --state=open --json url,updatedAt,commentsCount | Meeting 11 |
| Check that a PR is merged | gh pr view PR_URL --json state,mergedAt,baseRefName,mergeCommit | Meeting 12 |
Check that the merge reached the main branch (ahead or identical) | gh api repos/OWNER/REPO/compare/MERGE_SHA...DEFAULT_BRANCH --jq .status | Meeting 12 |
| Check CI on the commit you submit | gh run list --workflow ci.yml --commit "$(git rev-parse HEAD)" --json status,conclusion | Meeting 12 |
Check yourself: cover the Command column of one table, say each command and where it runs, then uncover and compare. Next week, do it again with another table.
Status codes in this course
These meanings are Recipe Box’s contract and retry policy, not a rule for every API: another service’s 429, for example, usually means a rate limit. Every error body uses FastAPI’s {"detail": ...} shape.
| Code | What it means here | Taught in |
|---|---|---|
| 200 OK | Success with a body: a list, one record, an update | Lecture 2 |
| 201 Created | A new record, returned in the body | Lecture 2 |
| 204 No Content | Success with an empty body: a delete | Lecture 2 |
| 404 Not Found | {"detail": "Not Found"}: no route matched, so check the path.{"detail": "Recipe not found"}: your handler ran and the id is missing | Lecture 2 |
| 405 Method Not Allowed | The path exists, but not with that method | Lecture 2 |
| 422 Unprocessable Content | The request broke the contract: a missing field, a value out of range or, in FastAPI, invalid JSON | Lecture 2 |
| 429 Too Many Requests | From the AI service: this run’s usage budget is spent. The backend does not retry it and answers 503 | Lecture 9 |
| 500 Internal Server Error | A bug on your side: the stack trace belongs in the server log, never in the reply. An AI-service 500 (a crash or a provider failure) is not retried; the backend answers 503 | Lecture 2 · Lecture 9 |
| 502 Bad Gateway | The AI service answered with something the backend cannot use: a 4xx, or a 200 that breaks the contract. From Lecture 9 the AI service also sends 502 when the model’s output is still invalid after the agent’s retries, and the backend passes it on as 502 without retrying | Lecture 7 · Lecture 9 |
| 503 Service Unavailable | A dependency is not available; try later. The backend’s answer when a call to the AI service is refused, fails DNS, times out, or gets a 500, 503 or 504. Lecture 7 maps every AI-service 5xx to 503; from Lecture 9 an AI-service 502 passes through as 502 | Lecture 7 · Lecture 9 |
| 504 Gateway Timeout | The AI service’s 25 s cap fired. Transient: the backend retries it, which runs the model again (paid), then answers 503 | Lecture 9 |
When you are behind
Find the earliest broken checkpoint: climb from rung 1, and the first check that fails is where to work. The learning map’s When you are behind gives the five repair steps, from “confirm the folder” to “restore the checkpoint before a stretch goal”.
| Rung | Check | Passes when | Taught in |
|---|---|---|---|
| 1. Tools | the Verify commands | each prints a version | Student setup |
| 2. Backend | curl http://localhost:8000/health | {"status":"ok"} | Lecture 1 |
| 3. API contract | uv run pytest in backend/ | all tests pass | Lecture 2 |
| 4. Durable data | Lecture 3’s restart test | data survives a restart | Lecture 3 |
| 5. Frontend | open the UI and list records | records appear; failures show a message | Lecture 4 · Lecture 5 |
| 6. AI service | its tests with TestModel | all tests pass, no model call | Lecture 6 |
| 7. Whole stack | docker compose up --build, then docker compose ps | every service shows healthy | Lecture 8 |
| 8. Release | CI on your commit | green | Lecture 10 |
Ask for help with PARD
Send all four parts to whoever you ask, human or AI, in the channel the instructor provides, with secrets redacted. PARD is also the skeleton of a good upstream bug report (Lecture 1).
Problem: one sentence
Action(s): the exact commands you ran
Result: the full output, pasted as text (not a screenshot)
Desired: what you expected
Before you ask, write one sentence saying what you think is wrong, and why: a debug log entry. A wrong guess is fine; it shows the helper where your picture differs from reality.
The open-source rule
Policy: Each student needs at least three distinct pull requests (PRs) of their own accepted and merged into established open-source projects; credit is per student, not per team, and each PR counts for one student only. A repository qualifies only when it meets all three conditions:
- The official public upstream repository on GitHub, under an open-source license, of an established project with ongoing maintainer activity.
- More than 10,000 GitHub stars on the day you open the PR; exactly 10,000 is not enough.
- Not a fork, a classroom repository, a personal copy, or a repository created to satisfy this assignment.
Quoted word for word from the course README, which remains the authority: read its qualifying repositories, what counts as merged and the deadline. Record each PR in your evidence table.
Terms
The glossary gives each course term one line and a link to where it is first taught, including every term in the lectures’ “Words you’ll meet today” lists. Its last line is a five-term drill to run before each lecture.