Standing on Other People's Code
Nobody writes date parsing or HTTP requests from scratch, because somebody has already written it better and tested it more. Install a real package, import it, and use in three lines what would take an afternoon to build.
Nobody writes date parsing or HTTP requests from scratch, because somebody has already written it better and tested it more. Install a real package, import it, and use in three lines what would take an afternoon to build.
pip installs code, not magic
$ $ pip install requests$ Successfully installed requests-2.31.0pip downloads the requests package from the Python Package Index and copies its files onto your machine — nothing more mysterious than that. Once installed, import requests works exactly like importing any module you wrote yourself.
$ >>> import requests$ >>> response = requests.get("https://api.github.com")$ >>> response.status_code$ 200That single install line usually pulls in more than one package. pip show requests lists certifi, charset-normalizer, idna, and urllib3 as requirements — packages requests depends on, that it needed you to have without ever asking you to install them yourself. Every one of them is now code running inside your program, whether you ever call it directly or not.
A virtual environment is a clean room per project
Installing packages globally means every project on the machine shares one set of versions — upgrade requests for one project, and a different project that needed the older version breaks without a single line of its own code changing.
$ $ python -m venv .venv$ $ source .venv/bin/activate$ (.venv) $ pip install requestspython -m venv .venv creates an isolated folder with its own copy of Python and its own package list. source .venv/bin/activate switches the current terminal to use that copy, so anything installed afterward stays scoped to this one project. The (.venv) prefix that appears in the prompt is the reminder that it worked — every pip install from here lands inside .venv, not on the machine at large.
deactivate switches the terminal back to whatever Python and packages exist outside the environment, and closing the terminal has the same effect. Neither one deletes anything — the folder is still there next time you activate it, packages and all.
Pinning versions so tomorrow matches today
pip install requests grabs whatever the newest version happens to be today. Run that same command again in a year, on a different machine, and it can install a different version — one that might behave differently, or not at all the way your code expects.
$ $ pip freeze > requirements.txt$ $ cat requirements.txt$ certifi==2024.2.2$ charset-normalizer==3.3.2$ idna==3.6$ requests==2.31.0$ urllib3==2.2.1pip freeze writes down the exact version of every package currently installed, not just the one you asked for by name — including the transitive dependencies pip pulled in on its own. Anyone who runs pip install -r requirements.txt against that file gets the identical set of versions you tested against, on any machine, at any later date.
Reading documentation instead of guessing at an API
response.status_code works because someone who wrote requests chose that name and documented it — there is no way to discover it by reading Python's own syntax rules, only by reading what the package actually promises.
$ >>> help(requests.get)$ Help on function get in module requests.api: $ get(url, params=None, **kwargs) Sends a GET request. ...help(requests.get) in a Python shell shows the function's own docstring immediately, without leaving the terminal — the fastest first move for a single function whose exact arguments you have forgotten. For anything past that, the package's own documentation site is written for exactly this question, and covers the shape of the whole library rather than one function at a time: which arguments are required, what a successful call returns, and which exceptions it can raise that a docstring alone would not mention.
A well-maintained package documents its arguments and return types precisely enough that you should never need to read its source code to use it correctly — needing to open the library's own internals just to call it is usually a sign the documentation, not your understanding, is the thing that is missing.
Deciding whether a package is worth depending on
pip install works identically whether the package behind it is maintained by a large team or was last touched by one person, three years ago, and then abandoned. The command gives no warning either way — that judgement is yours to make before you run it, not after something breaks.
Before you add a package you'll depend on for years
- →When was the last release? A package untouched for a few years may already be quietly broken against the Python version you're running.
- →How many other projects depend on it? Download counts on PyPI and stars or open issues on its repository are rough proxies for whether other people would notice, and fix, a serious bug.
- →What licence is it under? MIT and Apache-2.0 are safe for almost anything you'd build; some licences place real conditions on code that uses them, so check the licence before you build on it.
- →How many packages does it pull in underneath it? pip show <package> lists its direct dependencies — each one is someone else's code now running inside yours, whether you call it or not.
None of these rule a package out on their own — a young, actively maintained package with two dependencies is often the better bet over an old, unmaintained one with twenty, even if the old one has more stars from years ago. The point of the checklist is to make the trade-off visible before you commit to it, not to fail every package that trips one item.
Key takeaways
- pip install <package> downloads code from the Python Package Index and makes it importable, same as any module you wrote — often pulling in several more packages underneath it.
- A virtual environment gives each project its own isolated set of installed packages, so upgrading one project never breaks another.
- pip freeze > requirements.txt records the exact versions installed; a hand-written requirements.txt with >= is a wish about the future, not a lock on it.
- A package's own API — its function and argument names — can only be learned from its documentation or docstrings, not guessed from Python's syntax.
- A package worth depending on has recent maintenance, a licence you understand, and a dependency tree you've actually looked at — pip installs anything regardless.
Quick check
Answer these to unlock the next chapter — 3 of 4 to pass. You can retake it anytime.
Answer every question to check.
Make a free account to read on
Every chapter is free — an account is how your progress, XP, and streak follow you from your laptop to your phone, and how you show up on the leaderboard. No payment, no trial.