Code of the Day
BeginnerPackaging and Sharing

Packaging concepts

Packaging turns a script you run with "python script.py" into a tool you install once and run by name from anywhere.

UtilitiesBeginner6 min read
By the end of this lesson you will be able to:
  • Explain what a Python package is and what problem it solves
  • Describe what pyproject.toml declares
  • Understand how entry points map a command name to a Python function

You have built a utility that works. You run it with python extract.py score. That is fine for personal use, but it has a problem: you have to be in the right directory, Python has to be on the path, and anyone else who wants to use it has to find the file and remember the invocation. Packaging solves all of that.

What packaging does

A Python is a bundle that pip knows how to install. Once installed, the tool is available system-wide (or in the active virtual environment) by name — no directory navigation, no python prefix required. The same mechanism is what makes pip install requests work: you get a library you can import from anywhere.

For command-line utilities, packaging does two things:

  1. Puts your code somewhere Python can always find it (the site-packages directory).
  2. Creates a small executable wrapper — a script with the tool's name — that calls your main() function. That wrapper ends up on the shell's PATH, so typing extract score works from any directory inside the active .

pyproject.toml

pyproject.toml is the standard file that tells Python's build tools everything they need to know about your package:

  • name — the package identifier (what users type in pip install ...).
  • version — a version string. 0.1.0 is a fine starting point.
  • dependencies — other packages your tool requires (empty for simple utilities that only use the standard library).
  • entry points — the mapping from a command name to a Python function.

A minimal pyproject.toml for a utility looks like this:

[build-system]
requires = ["setuptools"]
build-backend = "setuptools.backends.legacy:build"

[project]
name = "extract"
version = "0.1.0"

[project.scripts]
extract = "extract:main"

The [project.scripts] section is where the magic happens. extract = "extract:main" means: create a command called extract that calls the main function in the extract module (i.e., extract.py).

Entry points in detail

The format for an entry point value is "module:function". When you run pip install -e . (more on that in the next lesson), pip generates a small wrapper script that does essentially this:

from extract import main
main()

That wrapper is placed in the virtual environment's bin/ directory (or Scripts/ on Windows), which is on the PATH. So typing extract in the terminal finds the wrapper, which calls your function.

Entry points are not limited to main(). You can expose multiple commands from a single package by adding more lines to [project.scripts]. A package could provide both extract and extract-validate, pointing at different functions in the same or different modules.

Where to go next

Next: packaging in Python — writing the actual pyproject.toml and using pip install -e . to install your utility for local development.

Finished reading? Mark it complete to track your progress.

On this page