GuideAdvanced
Python Packaging And Cli Tools
A script that "works on my machine" and an installable package someone else can actually use are two very different things, and this guide walks you from one to the other step by step. You work by packaging a single realistic case — `reservo`, a coworking room-booking system whose object model already exists — and turn it into an installable library with its own command-line tool. You'll learn what a module and a package are, how `import` and `sys.path` resolve, the modern `pyproject.toml` standard (PEP 621) and how to build a real wheel and sdist with `uv build`, how to isolate a project in virtual environments and manage dependencies with `pip` and `uv`, how to build a complete CLI with `argparse` (no external dependencies), how to expose it as an installed command via an entry point in `[project.scripts]`, how to structure a real package with submodules, relative imports, and a deliberate public API, and how to configure a quality toolchain (`ruff`, `mypy`, `pytest`, `pre-commit`). Everything runnable actually runs — the `reservo price --tier basic --hours 3` command prints `7500` from your terminal — the only thing taught as content without execution is publishing to PyPI, because that's a public, irreversible action. The final project integrates all seven pieces into a complete package, built, installed, and running end to end.
- 64
- lessons
- 8
- modules
- English · Spanish
- available in
- Yes
- certificate
- Free
- access
Outcomes
What you'll be able to do
- Distinguish a module from a package, understand what `__init__.py` does, and how Python resolves an `import` through `sys.path`
- Write a complete `pyproject.toml` following PEP 621 (metadata, dependencies, build backend) and build a real wheel and sdist with `uv build`
- Isolate a project in a virtual environment, manage dependencies with `pip` and `uv`, pin versions for reproducibility, and install in editable mode
- Build a complete command-line interface with `argparse`: subcommands, positional arguments and options, auto-generated help, and exit codes
- Expose a `main()` function as an installed PATH command via an entry point (`[project.scripts]`), and understand how the generated wrapper script works
- Apply semantic versioning and know the full distribution flow to PyPI/TestPyPI with `twine`
- Structure a real package into submodules with clear responsibilities, relative imports, `__main__.py`, and a one-way dependency (the CLI calls the library, never the reverse)
- Declare a deliberate public API with `__all__` and re-export it in `__init__.py`, and give `__version__` a single source of truth
- Configure a modern quality toolchain (`ruff` for lint and format, `mypy` for types, `pytest` wired in, `pre-commit` to automate it)
- Integrate every piece into a complete distributable package, built, installed, and verified with the CLI running from the PATH
Before you start
What you need to bring
It's for you if...
- Intermediate-level Python developers who've only written standalone scripts and never turned their code into an installable package
- Devs who want to give their own tool a professional command-line interface, with subcommands and auto-generated help
- People who need to understand `pyproject.toml` thoroughly because they see it in every modern project but never wrote one from scratch
- Anyone who wants to publish their first library to PyPI and wants to know the full flow before doing it for real
- Whoever maintains a single-file package that outgrew itself and needs a clear framework for structuring it into submodules
Requirements and materials
- Basic Python syntax: variables, functions, dictionaries, lists, control flow, and knowing how to write and run a `.py` file
- Minimal notions of classes (mastering object-oriented design is not required)
- Python 3.14 installed and a terminal
- No need to have used `pip`, `venv`, `uv`, or any packaging tool before: everything is explained from scratch
Content
The syllabus, module by module
Open any of them to see its lessons.
- 1. Introduction: From Script to Package
- 2. Why package — the loose script doesn't scale
- 3. Module vs package and `__init__.py`
- 4. How `import` and `sys.path` work
- 5. Absolute vs relative imports
- 6. The src layout and the bug it avoids
- 7. The first importable `reservo` package
- 8. Mini-project: your first package
- 1. Module introduction: from importable package to buildable package
- 2. `pyproject.toml`: the single file
- 3. The `[project]` table and its metadata
- 4. Dependencies and `requires-python`
- 5. The build backend: `[build-system]`
- 6. Building with `uv build`: wheel + sdist
- 7. What a wheel is vs an sdist (and inspecting it)
- 8. Mini-project: build `reservo`'s wheel
- 1. Module introduction: from buildable package to reproducible environment
- 2. Why isolate: the virtual environment
- 3. Creating and activating a virtual environment
- 4. pip: install, `freeze`, and `requirements.txt`
- 5. Pinning versions and reproducibility
- 6. The editable install: `pip install -e .`
- 7. uv: the modern manager (venv, install, lock)
- 8. Mini-project: a reproducible dev environment
- 1. Module introduction: give `reservo` an interface
- 2. What a CLI is and the basic `ArgumentParser`
- 3. Subcommands with `add_subparsers`
- 4. Positional arguments vs options
- 5. The autogenerated `--help` and argparse's error codes
- 6. The `main()` function and the exit code
- 7. Separating the CLI from the logic; `click` and `typer` as a concept
- 8. Mini-project: `reservo`'s CLI
- 1. Introduction: Entry points and distribution
- 2. What an entry point is and the `[project.scripts]` table
- 3. Install and run the `reservo` command
- 4. The generated wrapper and how it works
- 5. Semantic versioning
- 6. Publishing to PyPI and TestPyPI with `twine` (content)
- 7. What PyPI requires: metadata, README, and license
- 8. Mini-project: ship `reservo` as a command
- 1. Introduction: Structuring a real package
- 2. Splitting the code into submodules
- 3. Relative imports inside the package
- 4. `__main__.py` and `python -m reservo`
- 5. Separating the library from the CLI
- 6. The public API with `__all__` and re-exporting in `__init__.py`
- 7. `__version__` and the single source of truth
- 8. Mini-project: a well-structured `reservo`
- 1. Module introduction: the quality toolchain
- 2. Why a quality toolchain
- 3. `ruff`: lint vs. format, and how to configure it
- 4. Type annotations and `mypy`
- 5. Configuring `mypy` in strict mode in `pyproject.toml`
- 6. The hook into `pytest`: wiring it up with `[tool.pytest.ini_options]`
- 7. `pre-commit`: automating the toolchain
- 8. Mini-project: a quality toolchain for `reservo`
- 1. Introduction: Package and ship `reservo`
- 2. The complete src layout and the public API
- 3. `pyproject.toml`: metadata, entry point, and toolchain
- 4. The integrated `argparse` CLI
- 5. Building the wheel with `uv build`
- 6. Installing and running the `reservo` command
- 7. Preparing the `twine upload` (content)
- 8. Project: build, package, and ship `reservo`
Common questions
What people usually ask
No limit. It's a free guide: come in whenever you like, as often as you like.
No. Modules run from easier to harder, but you can jump to the one you need. Progress is saved per lesson.
Whatever is needed is listed under “What you need to bring”, above. If nothing is listed there, you can start from zero.
In the Club's WhatsApp group, and every two weeks there's a live with an instructor where questions get worked through.
Yes. It's issued automatically once you finish every lesson, with a verifiable code you can share on LinkedIn.
Start whenever you like
What students say
These reviews are from enrolled students who completed at least 50% of the course. We moderate reviews only on content grounds (spam, offensive language, personal data), never for being critical or negative.
No approved reviews yet.
Be the first to share your experience!