Mailroom – as a Python Package
The mailroom program is a small but complete system. If you wanted to make it available for others to test and run, making a “proper” python package is a great idea. Making a package of it will also make it easier to develop and test, even if you are the only one to use it.
Code Structure
Start with your existing version of mailroom.
It may already be structured with the “logic” code distinct from the user interface. (Yes, a command line is a user interface.) But you may have it all in one file. This isn’t too bad for such a small program, but as a program grows, you really want to keep things separate, in a well organized package.
The first step is to re-structure your code into separate files:
One (or more) for the logic code: the code that manipulates the data
One for the user-interface code: the code with the interactive loops and all the “input” and “print” statements
One (or more) for the unit tests.
You should have all this pretty distinct after having refactored for the unit testing. If not, this is a good time to do it!
In addition to those three, you will need a single function to call that will start the program. That can be defined in a new file, as a “script”, but for something as simple as this, it can be in with your interface code. That file can then have an if __name__ == "__main__"
block which should be as simple as:
if __name__ == "__main__":
main()
Making the Package
Put all these in a python package structure, something like this:
└── mailroom
├── pyproject.toml
└── mailroom
├── __init__.py
├── cli.py
├── model.py
└── tests
├── __init__.py
├── test_cli.py
└── test_model.py
You will need to import the logic code from model.py in the cli code in order to use it.
You can wait until you learn about mocking to write the code in test_cli.py, so you can leave that out for now.
Now write a pyproject.toml
file to support the installation of your package.
Making the Top-Level Script Runnable
To get the script installed you have two options. I used to prefer the more straightforward one, the project.scripts configuration.
Using this configuration you will end up with an executable Python script that starts your program. The configuration to achieve this should look something like this:
[project.scripts]
mailroom = "mailroom.cli:main"
The basic syntax is pretty straightforward. You want a program called mailroom
that calls the main
function in the the mailroom.cli
module. That’s it. You can have multiple entries if you want to have multiple scripts. Just follow the same syntax.
setuptools
will create a wrapper script with the name given, and that wrapper will call the function in the module that is specified.
Once this is all set up, and you install the package, either in editable mode or not:
$ python3 -m pip install -e .
You should then be able to type “mailroom” at the command line and have your program run.
Testing your Package
When you are done, you should be able to both install your package fully:
$ python3 -m pip install .
Or in “editable” mode:
$ python3 -m pip install -e .
When that is done, you should be able to run the top-level script from anywhere:
$ mailroom
And run the test from within the package:
$ pytest --pyargs mailroom
Or you can run the tests from the test dir as well.
If you installed in editable mode, then you can update the code and re-run the tests or the script, and it will use the new code right away.