Why I Built “mypip”

A Solution to a Missing pip Feature I Desperately Needed

Fullstack CTO

--

As a Python developer, I’ve always admired the simplicity and power of Python’s package management system, pip. It's straightforward, easy to use, and gets the job done. However, there's been one feature I've found myself missing time and time again, something that users of npm (Node Package Manager) take for granted: the ability to save a newly installed package directly to the project's dependencies list with a simple command-line option.

In the Node.js ecosystem, when you install a package using npm and want to add it to your project’s dependencies, all you need to do is append the -S or --save flag to your install command. This handy option automatically adds the installed package and its version to your package.json, streamlining the workflow and ensuring that anyone else working on the project can replicate the environment with ease.

Unfortunately, pip lacks an equivalent feature out of the box. The closest we get is the pip freeze command, which outputs a list of all installed packages in the current environment, along with their exact versions. While useful, pip freeze has its drawbacks, particularly for my workflow. It lists every installed package, not just those directly related to the project. This can lead to bloated requirements.txt files, including unnecessary dependencies that can cause headaches and compatibility issues down the line. Moreover, when sharing or deploying applications, these exhaustive lists can lead to installation problems, especially when specific versions of packages are not compatible across different environments.

Frustrated with this limitation and determined to find a solution, I decided to take matters into my own hands. The result is mypip, a simple wrapper around pip that introduces the -S (save) flag functionality, mirroring the convenience offered by npm.

Here’s how it works: when installing a new package, you simply use mypip install <package-name> -S. The tool takes care of installing the package using pip and then appends the package and its exact installed version to your requirements.txt file. This approach ensures that only the packages you explicitly install and wish to track are added to your project's dependencies, keeping your requirements.txt clean and manageable.

Building mypip involved creating a Bash script that wraps around the pip command. The script intercepts the -S flag and, after running the usual pip install, it uses pip freeze to find the version of the newly installed package and adds it to requirements.txt. This way, mypip maintains the ease of use of pip while avoiding the all-or-nothing approach of pip freeze.

The development of mypip has been a journey of necessity, born out of a gap in my daily programming tools. It's a testament to the flexibility and openness of the Python community, where if you find something lacking, you have the power and the means to create a solution. mypip has significantly streamlined my workflow, ensuring that my project dependencies are always accurately and efficiently managed.

For those interested, the script is straightforward to implement and customize according to your needs. It’s a small step towards making Python’s package management system even more powerful and user-friendly, and I hope it helps others as much as it has helped me.

Usage

To install a package and add it to your requirements.txt, simply use:

mypip install package-name -S

mypip will install the package using pip and append the installed package along with its version to the requirements.txt file in the current directory.

mypip install requests -S

This command installs the requests library and adds its current version to requirements.txt.

--

--