Skip to content

Commit 7bddb47

Browse files
travisjneumanclaude
andcommitted
feat: add step-by-step WALKTHROUGH.md for 12 module first-projects
Add guided walkthroughs for the first project in each expansion module: web-scraping, CLI tools, REST APIs, FastAPI, async Python, SQLite, pandas, pytest parametrize, Docker, Django, package publishing, and cloud deployment. Each walkthrough follows the established format with thinking process, 4-6 steps, predict-before-you-scroll prompts, common mistakes table, and learning summary. Also updates guide indexes and README badges to reflect new content. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 04ff6b9 commit 7bddb47

File tree

16 files changed

+2063
-6
lines changed

16 files changed

+2063
-6
lines changed

README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
<img src="https://img.shields.io/badge/Curriculum_Docs-50+-f57c00?style=for-the-badge" alt="50+ Curriculum Docs">
1212
<img src="https://img.shields.io/badge/Concept_Guides-35-7c4dff?style=for-the-badge" alt="35 Concept Guides">
1313
<img src="https://img.shields.io/badge/Quizzes-34-e53935?style=for-the-badge" alt="34 Quizzes">
14+
<img src="https://img.shields.io/badge/Walkthroughs-51-00bcd4?style=for-the-badge" alt="51 Walkthroughs">
15+
<img src="https://img.shields.io/badge/Diagrams-36-ff9800?style=for-the-badge" alt="36 Diagrams">
16+
<img src="https://img.shields.io/badge/Video_Guides-40-c62828?style=for-the-badge" alt="40 Video Guides">
1417
<a href="./LICENSE"><img src="https://img.shields.io/badge/License-MIT-blue?style=for-the-badge" alt="MIT License"></a>
1518
<img src="https://img.shields.io/badge/Contributions-Welcome-brightgreen?style=for-the-badge" alt="Contributions Welcome">
1619
</p>
@@ -199,8 +202,8 @@ One quiz per concept guide. Run them from the terminal:
199202
python concepts/quizzes/what-is-a-variable-quiz.py
200203
```
201204

202-
### Flashcards (16 decks)
203-
Spaced repetition cards using a Leitner box system. Cards you get right appear less often. Cards you miss come back immediately. Decks cover all 13 levels plus 4 expansion modules.
205+
### Flashcards (24 decks)
206+
Spaced repetition cards using a Leitner box system. Cards you get right appear less often. Cards you miss come back immediately. Decks cover all 13 levels plus 11 expansion modules.
204207
```bash
205208
python practice/flashcards/review-runner.py
206209
```

guides/DIAGRAM_INDEX.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,19 @@ Each diagram page includes: an overview map, step-by-step execution flow, decisi
4949
| Regex | [Diagrams](../concepts/diagrams/regex-explained.md) | Matching flow, pattern decision tree |
5050
| Security Basics | [Diagrams](../concepts/diagrams/security-basics.md) | OWASP overview, sanitization flow |
5151

52+
## Module Architecture
53+
54+
| Module | Diagram Page | Diagram Types |
55+
|--------|-------------|---------------|
56+
| FastAPI | [Diagrams](../concepts/diagrams/fastapi-request-lifecycle.md) | Request lifecycle, dependency injection flow |
57+
| Django | [Diagrams](../concepts/diagrams/django-mtv-pattern.md) | MTV pattern, URL routing, ORM flow |
58+
| Docker | [Diagrams](../concepts/diagrams/docker-architecture.md) | Container lifecycle, compose services, networking |
59+
| Async Event Loop | [Diagrams](../concepts/diagrams/async-event-loop.md) | Event loop states, task scheduling, gather vs wait |
60+
| SQLAlchemy ORM | [Diagrams](../concepts/diagrams/sqlalchemy-orm-mapping.md) | Engine/Session/Model mapping, query execution |
61+
| Web Scraping | [Diagrams](../concepts/diagrams/web-scraping-pipeline.md) | Fetch/parse/extract pipeline, rate limiting |
62+
| CI/CD | [Diagrams](../concepts/diagrams/ci-cd-pipeline.md) | Push/lint/test/build/deploy stages |
63+
| Cloud Deployment | [Diagrams](../concepts/diagrams/cloud-deployment-topology.md) | Local/staging/production topology |
64+
5265
---
5366

5467
## How to Read Mermaid Diagrams

guides/VIDEO_INDEX.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,23 @@ All videos are freely available on YouTube. No accounts or payments required.
4949
| Security Basics | [Videos](../concepts/videos/security-basics.md) ||
5050
| Debugging Methodology | [Videos](../concepts/videos/debugging-methodology.md) ||
5151

52+
## Expansion Modules
53+
54+
| Module | Video Page | Primary Creator |
55+
|--------|-----------|-----------------|
56+
| Web Scraping | [Videos](../concepts/videos/web-scraping.md) ||
57+
| CLI Tools | [Videos](../concepts/videos/cli-tools.md) ||
58+
| REST API Clients | [Videos](../concepts/videos/rest-apis-client.md) ||
59+
| FastAPI | [Videos](../concepts/videos/fastapi.md) ||
60+
| Async Python | [Videos](../concepts/videos/async-python.md) ||
61+
| Databases & ORM | [Videos](../concepts/videos/databases-orm.md) ||
62+
| Data Analysis | [Videos](../concepts/videos/data-analysis.md) ||
63+
| Advanced Testing | [Videos](../concepts/videos/testing-advanced.md) ||
64+
| Docker & Deployment | [Videos](../concepts/videos/docker-deployment.md) ||
65+
| Django Full-Stack | [Videos](../concepts/videos/django-fullstack.md) ||
66+
| Package Publishing | [Videos](../concepts/videos/package-publishing.md) ||
67+
| Cloud Deploy | [Videos](../concepts/videos/cloud-deploy.md) ||
68+
5269
---
5370

5471
## Recommended YouTube Channels

guides/WALKTHROUGH_INDEX.md

Lines changed: 57 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,17 +71,70 @@ Each walkthrough covers: understanding the problem, planning before code, buildi
7171
| 08 Cross-File Joiner | [Walkthrough](../projects/level-5/08-cross-file-joiner/WALKTHROUGH.md) | Multi-file operations |
7272
| 15 Level 5 Mini Capstone | [Walkthrough](../projects/level-5/15-level5-mini-capstone/WALKTHROUGH.md) | Combining level 5 skills |
7373

74-
## Levels 6-10
74+
## Level 6
7575

76-
*In progress — walkthroughs being created for advanced projects.*
76+
| Project | Walkthrough | Focus |
77+
|---------|------------|-------|
78+
| 01 SQL Connection Simulator | [Walkthrough](../projects/level-6/01-sql-connection-simulator/WALKTHROUGH.md) | SQL patterns |
79+
| 08 Data Lineage Capture | [Walkthrough](../projects/level-6/08-data-lineage-capture/WALKTHROUGH.md) | Data lineage tracking |
80+
| 15 Level 6 Mini Capstone | [Walkthrough](../projects/level-6/15-level6-mini-capstone/WALKTHROUGH.md) | Combining level 6 skills |
81+
82+
## Level 7
83+
84+
| Project | Walkthrough | Focus |
85+
|---------|------------|-------|
86+
| 01 API Query Adapter | [Walkthrough](../projects/level-7/01-api-query-adapter/WALKTHROUGH.md) | API integration |
87+
| 08 Ingestion Observability Kit | [Walkthrough](../projects/level-7/08-ingestion-observability-kit/WALKTHROUGH.md) | Observability patterns |
88+
| 15 Level 7 Mini Capstone | [Walkthrough](../projects/level-7/15-level7-mini-capstone/WALKTHROUGH.md) | Combining level 7 skills |
89+
90+
## Level 8
91+
92+
| Project | Walkthrough | Focus |
93+
|---------|------------|-------|
94+
| 01 Dashboard KPI Assembler | [Walkthrough](../projects/level-8/01-dashboard-kpi-assembler/WALKTHROUGH.md) | KPI dashboards |
95+
| 08 Fault Injection Harness | [Walkthrough](../projects/level-8/08-fault-injection-harness/WALKTHROUGH.md) | Chaos engineering |
96+
| 15 Level 8 Mini Capstone | [Walkthrough](../projects/level-8/15-level8-mini-capstone/WALKTHROUGH.md) | Combining level 8 skills |
97+
98+
## Level 9
99+
100+
| Project | Walkthrough | Focus |
101+
|---------|------------|-------|
102+
| 01 Architecture Decision Log | [Walkthrough](../projects/level-9/01-architecture-decision-log/WALKTHROUGH.md) | Architecture decisions |
103+
| 07 Canary Rollout Simulator | [Walkthrough](../projects/level-9/07-canary-rollout-simulator/WALKTHROUGH.md) | Deployment strategies |
104+
| 15 Level 9 Mini Capstone | [Walkthrough](../projects/level-9/15-level9-mini-capstone/WALKTHROUGH.md) | Combining level 9 skills |
105+
106+
## Level 10
107+
108+
| Project | Walkthrough | Focus |
109+
|---------|------------|-------|
110+
| 01 Enterprise Python Blueprint | [Walkthrough](../projects/level-10/01-enterprise-python-blueprint/WALKTHROUGH.md) | Enterprise patterns |
111+
| 08 Zero-Downtime Migration Lab | [Walkthrough](../projects/level-10/08-zero-downtime-migration-lab/WALKTHROUGH.md) | Migration strategies |
112+
| 15 Level 10 Grand Capstone | [Walkthrough](../projects/level-10/15-level10-grand-capstone/WALKTHROUGH.md) | Combining all skills |
77113

78114
## Elite Track
79115

80-
*In progress — walkthroughs being created for elite engineering projects.*
116+
| Project | Walkthrough | Focus |
117+
|---------|------------|-------|
118+
| 01 Algorithms & Complexity Lab | [Walkthrough](../projects/elite-track/01-algorithms-complexity-lab/WALKTHROUGH.md) | Algorithm analysis |
119+
| 05 Performance Profiler Workbench | [Walkthrough](../projects/elite-track/05-performance-profiler-workbench/WALKTHROUGH.md) | Performance profiling |
120+
| 10 Staff Engineer Capstone | [Walkthrough](../projects/elite-track/10-staff-engineer-capstone/WALKTHROUGH.md) | Staff-level engineering |
81121

82122
## Expansion Modules
83123

84-
*Coming soon — walkthroughs for the first project in each module.*
124+
| Module | Walkthrough | Focus |
125+
|--------|------------|-------|
126+
| 01 Web Scraping | [Walkthrough](../projects/modules/01-web-scraping/01-fetch-a-webpage/WALKTHROUGH.md) | requests, BeautifulSoup |
127+
| 02 CLI Tools | [Walkthrough](../projects/modules/02-cli-tools/01-click-basics/WALKTHROUGH.md) | click, typer |
128+
| 03 REST APIs | [Walkthrough](../projects/modules/03-rest-apis/01-first-api-call/WALKTHROUGH.md) | API consumption |
129+
| 04 FastAPI | [Walkthrough](../projects/modules/04-fastapi-web/01-hello-fastapi/WALKTHROUGH.md) | FastAPI basics |
130+
| 05 Async Python | [Walkthrough](../projects/modules/05-async-python/01-async-basics/WALKTHROUGH.md) | asyncio fundamentals |
131+
| 06 Databases & ORM | [Walkthrough](../projects/modules/06-databases-orm/01-sqlite-basics/WALKTHROUGH.md) | SQLite, SQLAlchemy |
132+
| 07 Data Analysis | [Walkthrough](../projects/modules/07-data-analysis/01-pandas-basics/WALKTHROUGH.md) | pandas basics |
133+
| 08 Advanced Testing | [Walkthrough](../projects/modules/08-testing-advanced/01-parametrize/WALKTHROUGH.md) | pytest parametrize |
134+
| 09 Docker | [Walkthrough](../projects/modules/09-docker-deployment/01-first-dockerfile/WALKTHROUGH.md) | Dockerfile basics |
135+
| 10 Django | [Walkthrough](../projects/modules/10-django-fullstack/01-django-setup/WALKTHROUGH.md) | Django setup |
136+
| 11 Package Publishing | [Walkthrough](../projects/modules/11-package-publishing/01-package-structure/WALKTHROUGH.md) | pyproject.toml |
137+
| 12 Cloud Deploy | [Walkthrough](../projects/modules/12-cloud-deploy/01-deploy-to-railway/WALKTHROUGH.md) | Railway deployment |
85138

86139
---
87140

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
# Fetch a Webpage — Step-by-Step Walkthrough
2+
3+
[<- Back to Project README](./README.md)
4+
5+
## Before You Start
6+
7+
Read the [project README](./README.md) first. Try to solve it on your own before following this guide. Spend at least 15 minutes attempting it independently. The goal is to fetch a webpage with `requests.get()`, check the status code, and print some of the HTML content. If you can do that much, you are on the right track.
8+
9+
## Thinking Process
10+
11+
When you hear "fetch a webpage," think about what your browser does when you type a URL and press Enter. It sends an HTTP GET request to a server, the server sends back a response (status code, headers, and a body of HTML), and your browser renders the HTML into a visual page. Your Python script does the same thing, except instead of rendering the page, you inspect the raw response.
12+
13+
The `requests` library is Python's most popular tool for making HTTP requests. It wraps the messy details of HTTP into a clean, simple API. The response object it returns has everything: the status code (did it work?), the headers (metadata about the response), and the body text (the actual HTML). Your job is to call `requests.get()`, check whether the request succeeded, and display the interesting parts.
14+
15+
Start by thinking about what could go wrong. The server might not exist (connection error). The page might not exist (404 status). The server might be overloaded (500 status). Handling these cases is what separates a script that works from one that is actually useful.
16+
17+
## Step 1: Import requests and Define the URL
18+
19+
**What to do:** Import the `requests` library and choose a URL to fetch.
20+
21+
**Why:** The `requests` library does not come with Python — you installed it with `pip install requests`. The URL `http://books.toscrape.com/` is a website built specifically for scraping practice, so you will never get blocked or cause problems by fetching it.
22+
23+
```python
24+
import requests
25+
26+
url = "http://books.toscrape.com/"
27+
```
28+
29+
**Predict:** What happens if you try to run the script without installing `requests` first? What does the error message look like?
30+
31+
## Step 2: Send the GET Request
32+
33+
**What to do:** Call `requests.get(url)` and store the response object.
34+
35+
**Why:** `requests.get()` sends an HTTP GET request — the same type of request your browser sends when you visit a URL. The function returns a `Response` object that contains everything the server sent back. Think of it as an envelope: the status code is stamped on the outside, the headers are metadata inside the flap, and the body (HTML) is the letter inside.
36+
37+
```python
38+
print(f"Fetching {url} ...")
39+
response = requests.get(url)
40+
```
41+
42+
**Predict:** After this line runs, `response` holds the entire server response. What type is `response`? Try `print(type(response))` to find out.
43+
44+
## Step 3: Check the Status Code
45+
46+
**What to do:** Read `response.status_code` and decide what to do based on its value.
47+
48+
**Why:** The status code tells you whether the request succeeded. 200 means "OK" — the server found the page and sent it back. 404 means "not found." 500 means the server had an internal error. Checking the status code before processing the response prevents you from trying to read HTML that does not exist.
49+
50+
```python
51+
if response.status_code == 200:
52+
print(f"Status code: {response.status_code}")
53+
# Proceed to display the content
54+
else:
55+
print(f"Request failed with status code: {response.status_code}")
56+
```
57+
58+
**Predict:** If you change the URL to `http://books.toscrape.com/this-does-not-exist`, what status code will you get?
59+
60+
## Step 4: Inspect Headers and Content
61+
62+
**What to do:** Print the Content-Type header and a preview of the response body.
63+
64+
**Why:** Headers are metadata that the server sends along with the response. The `Content-Type` header tells you what kind of content came back (HTML, JSON, an image, etc.). The response body (`response.text`) is the actual content — in this case, raw HTML. Printing the first 500 characters gives you a preview without flooding your terminal.
65+
66+
```python
67+
content_type = response.headers.get("Content-Type", "unknown")
68+
print(f"Content type: {content_type}")
69+
print(f"Content length: {len(response.text)} characters")
70+
71+
print("\nFirst 500 characters of the page:")
72+
print("-" * 50)
73+
print(response.text[:500])
74+
print("-" * 50)
75+
```
76+
77+
Two details to notice:
78+
79+
- **`response.headers.get("Content-Type", "unknown")`** uses `.get()` with a default value instead of direct bracket access. This prevents a crash if the header is missing.
80+
- **`response.text[:500]`** is a string slice. It returns the first 500 characters. The full HTML of a webpage can be thousands of characters long.
81+
82+
**Predict:** What is the difference between `response.text` and `response.content`? Try printing both and look at the types.
83+
84+
## Step 5: Wrap It in a Function and Add a Main Guard
85+
86+
**What to do:** Organize your code into functions and add the `if __name__ == "__main__"` guard.
87+
88+
**Why:** Putting the logic in functions makes the code reusable — another script could import `fetch_page()` without running the whole program. The `__name__` guard ensures `main()` only runs when you execute the file directly, not when someone imports it.
89+
90+
```python
91+
def fetch_page(url):
92+
print(f"Fetching {url} ...")
93+
response = requests.get(url)
94+
return response
95+
96+
def display_response_info(response):
97+
print(f"Status code: {response.status_code}")
98+
# ... rest of the display logic
99+
100+
def main():
101+
url = "http://books.toscrape.com/"
102+
response = fetch_page(url)
103+
if response.status_code == 200:
104+
display_response_info(response)
105+
else:
106+
print(f"Request failed with status code: {response.status_code}")
107+
print("\nDone.")
108+
109+
if __name__ == "__main__":
110+
main()
111+
```
112+
113+
**Predict:** What happens if you import this file from another Python file? Does `main()` run?
114+
115+
## Common Mistakes
116+
117+
| Mistake | Why It Happens | Fix |
118+
|---------|---------------|-----|
119+
| `ModuleNotFoundError: No module named 'requests'` | `requests` is not installed | Run `pip install requests` in your terminal |
120+
| Printing `response` instead of `response.text` | Confusion between the object and its content | `response` is the whole object; `.text` is the HTML string |
121+
| Not checking the status code | Assuming every request succeeds | Always check `response.status_code` before processing |
122+
| Using `response.content` when you want text | Mixing up bytes and strings | `.text` returns a string (decoded), `.content` returns raw bytes |
123+
124+
## Testing Your Solution
125+
126+
There are no pytest tests for this project — it is a script that fetches a live website. Run it and check the output:
127+
128+
```bash
129+
python project.py
130+
```
131+
132+
Expected output:
133+
```text
134+
Fetching http://books.toscrape.com/ ...
135+
Status code: 200
136+
Content type: text/html
137+
Content length: 51696 characters
138+
...
139+
Done.
140+
```
141+
142+
The exact character count may vary, but you should see status code 200 and recognizable HTML tags.
143+
144+
## What You Learned
145+
146+
- **`requests.get()`** sends an HTTP GET request and returns a Response object — the same kind of request your browser makes when you visit a URL.
147+
- **Status codes** tell you whether a request succeeded (200), the page was not found (404), or the server had an error (500). Always check before processing.
148+
- **`response.text`** gives you the response body as a string, while **`response.headers`** gives you the metadata the server sent back.
149+
- **The `if __name__ == "__main__"` pattern** lets you write code that works both as a standalone script and as an importable module.

0 commit comments

Comments
 (0)