Point the image download at a host that still serves it - #440
Conversation
image_transformation.ipynb cannot run past its second cell. The image URL returns 404, so image.jpeg is written from an HTML error page and PIL raises on the next cell. Every transformation in the notebook is downstream of that. Wikimedia Commons has a stable copy of the same photograph. It requires a descriptive User-Agent, so the stock python-requests one draws a 403 and that alone would leave the notebook just as broken. Both are handled here. The original is several thousand pixels on a side, so scale it to 800px wide after loading, which keeps the transformation cells quick. A raise_for_status call turns any future outage into an error at the download rather than a confusing one inside PIL.
There was a problem hiding this comment.
🟡 Changes recommended
The updated download/load cells still have a couple of reliability/quality issues (notably no request timeout and default nearest-neighbor resize) that should be addressed before approval.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Updates the image download and loading steps in the TensorFlow v2 “image_transformation” notebook so it runs end-to-end again by switching to a currently available image source and making failures surface at the download step.
Changes:
- Replace the broken image URL with a Wikimedia-hosted copy and set an explicit, descriptive
User-Agent. - Add
raise_for_status()so HTTP failures fail early instead of later inside PIL. - Resize the loaded image to ~800px wide to keep subsequent transformation steps fast and display-friendly.
File summaries
| File | Description |
|---|---|
| tensorflow_v2/notebooks/5_DataManagement/image_transformation.ipynb | Fixes the notebook’s image fetch/load pipeline by updating the download URL + headers, adding HTTP error handling, and resizing the image for usability. |
Review details
- Files reviewed: 1/1 changed files
- Comments generated: 2
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| "# copy, but requires a descriptive User-Agent rather than the requests default.\n", | ||
| "headers = {\"User-Agent\": \"TensorFlow-Examples (https://github.com/aymericdamien/TensorFlow-Examples)\"}\n", | ||
| "url = \"https://upload.wikimedia.org/wikipedia/commons/8/85/Tour_Eiffel_Wikimedia_Commons_%28cropped%29.jpg\"\n", | ||
| "d = requests.get(url, headers=headers)\n", |
There was a problem hiding this comment.
Taken, and fixed in 206e03e: the download now passes timeout=30.
You are right about the failure mode being the notable part. Without a timeout a stalled host hangs the cell with no output at all, which in a teaching notebook reads as the example being broken rather than as the network being slow. That is the same confusion this pull request is fixing at the other end, where an unchecked error response surfaced two cells later as an unreadable image.
| "img = PIL.Image.open('image.jpeg')\n", | ||
| "img.load()\n", | ||
| "# Scale to a workable size; the original is several thousand pixels on a side.\n", | ||
| "img = img.resize((800, round(800 * img.height / img.width)))\n", |
There was a problem hiding this comment.
The rescale is gone in 206e03e, so this is moot in the diff, but the resampling half of the point is worth correcting for the record rather than leaving as agreed-by-silence.
PIL.Image.resize does not default to nearest-neighbor for an image like this one. Pillow resolves resample=None per mode:
if resample is None:
type_special = ";" in self.mode
resample = Resampling.NEAREST if type_special else Resampling.BICUBIC
The Eiffel Tower JPEG loads as RGB, so the default here was BICUBIC, not NEAREST. Checked against the installed Pillow 10.4.0 source rather than from memory. NEAREST would apply only to a mode carrying a ";", such as the raw integer modes.
Your aliasing concern would have been right had the default been NEAREST, and the reasoning from it to downstream transformation outputs is sound; it is the premise that does not hold.
The rescale was removed for a different reason: resizing changes what every transformation cell operates on, which is more than a download repair should do. So the rounding question does not arise either.
|
这是来自QQ邮箱的假期自动回复邮件。您好,您的邮件已经收到。谢谢您,祝顺利。
|
|
已经收到您的邮件。
|
Two changes from review. The rescale is removed. Resizing the image changes what every transformation cell below it operates on, which is more than repairing a download needs to do, and a notebook demonstrating image transformations should show them on the image it fetched rather than on one this change decided to substitute. The original is large, but that is the notebook's business rather than this fix's. The download gains timeout=30. Without it a stalled connection hangs the cell indefinitely with no output, which in a teaching notebook reads as the example being broken rather than as the network being slow. What remains is only what the notebook cannot run without: a descriptive User-Agent, the URL of a host that still serves the image, and raise_for_status so a future outage surfaces at the download rather than as an unreadable image two cells later.
The notebook
tensorflow_v2/notebooks/5_DataManagement/image_transformation.ipynbcannot run past its second cell today.The download cell asks for:
That returns 404 with an HTML body, which the cell writes into
image.jpegunchecked. ThePIL.Image.opencall then raises in the next cell, and since every transformation in the notebook operates onimg_array, none of them run.The Change
Wikimedia Commons has a stable copy of the same photograph. Two details are needed to use it, and either one alone still leaves the notebook broken:
requestsUser-AgentThe Wikimedia policy rejects the stock
python-requestsUser-Agent, so the download sets a descriptive one naming this project.The original is several thousand pixels on a side, so the load cell scales it to 800px wide. That keeps the transformation cells quick and the displayed images a sensible size.
The change also adds a
raise_for_status()call so a future outage surfaces as an error at the download rather than as a confusing one inside PIL.Notes
sourcearrays change. Stored outputs are untouched: 8 insertions, 1 deletion.