Skip to Content
Course content

348: Defining Console Script Entry Points

Click on the "Edit" button in the top corner of the screen to edit your slide content.

How do I actually make a command that runs my code after someone installs my package?

You've probably used tools like black or pytest where you just type the name into your terminal and it works. You didn't have to type python -m pytest every time. That's because those packages defined a "console script entry point."

In a modern Python project, you do this in your pyproject.toml file. You aren't writing a bash script; you're telling the installer (like pip) to create a tiny executable wrapper for you. Let's say you've built a small tool called task-master to manage a to-do list. Your project structure looks like this:

task_master/
├── pyproject.toml
└── src/
    └── task_master/
        ├── __init__.py
        └── cli.py

Inside your pyproject.toml, you add a [project.scripts] section. It looks like a dictionary where the key is the command you want the user to type, and the value is the path to the function that should execute:

[project.scripts]
task-master = "task_master.cli:main"

When a user runs pip install ., pip sees this and generates a task-master executable in the environment's bin (or Scripts on Windows) folder. Now, they just type task-master and your code runs.

Does the function have to be named "main", or can I call it whatever I want?

It can be anything. The "task_master.cli:main" syntax is just a pointer. The part before the colon is the module path, and the part after the colon is the specific function name. I've seen people use run(), start(), or even launch_rocket().

Here is how that cli.py might look:

def start_app():
    print("Welcome to Task-Master! Your list is currently empty.")
    # Your logic goes here...

If you named your function start_app, you'd just update your pyproject.toml to match:

[project.scripts]
task-master = "task_master.cli:start_app"

One thing to keep in mind: the function cannot take any required arguments. The wrapper created by pip calls the function with zero arguments. If you need to handle user input, you'll want to use sys.argv or a library like argparse or click inside that function.

What happens if I change the function name or the command name later?

This is where things get a bit annoying if you aren't careful. Because pip creates a physical file on the disk during installation, simply changing the pyproject.toml file and saving it doesn't update the command in your terminal. The "link" is already baked into the installation.

If you change task-master to tm in your config, you have to re-install the package for the change to take effect. If you're developing the tool locally, I highly recommend installing your package in "editable" mode:

pip install -e .

Even with editable mode, though, changes to the [project.scripts] section usually require a re-install because the entry point script itself needs to be created or renamed in the system path. I've lost plenty of hours wondering why my new command wasn't working, only to realize I forgot to run pip install . again after tweaking the config.




📋 Practical Task

Build the "Quick-Note" Terminal Command

Your goal is to create a package that allows a user to type qnote into their terminal to print a "Note of the Day."

  • Create a directory named quick_note.
  • Inside, create a pyproject.toml file. Define a project name and version, and add a [project.scripts] section that maps the command qnote to a function named display_note inside a module named notes.engine.
  • Create a sub-folder structure quick_note/notes/ containing an __init__.py and an engine.py.
  • In engine.py, define the display_note() function to print "Don't forget to drink water today!" to the console.
  • Install your package locally using pip install . and verify that typing qnote in your terminal executes the function.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.