- Discuss the basic directory structure of a CLI.
- Outline the first steps in building a CLI.
You now have a basic idea of what constitutes a CLI, but you (understandably!) likely don't have the best idea of where to start. Fork and clone this lesson for a template for your CLI. Take a look at the directory structure before we begin:
.
├── Pipfile
├── Pipfile.lock
├── README.md
└── lib
├── cli.py
├── db
│ ├── models.py
│ └── seed.py
├── debug.py
└── helpers.py
Note: You may already know some or all of the material covered in this lesson. We hope that having it all in one place will help you in designing and developing your project, regardless of where you're starting off.
This project will likely be one of the biggest projects you've undertaken so far. Your first task should be creating a Git repository to keep track of your work and roll back any undesired changes.
If you're using this template, start off by removing the existing metadata for Github and Canvas. Run the following command to carry this out:
$ rm -rf .git .github .canvas
The rm
command removes files from your computer's memory. The -r
flag tells
the console to remove recursively, which allows the command to remove
directories and the files within them. -f
removes them permanently.
.git
contains this directory's configuration to track changes and push to
Github (you want to track and push your own changes instead), and .github
and .canvas
contain the metadata to create a Canvas page from your Git repo.
You don't have the permissions to edit our Canvas course, so it's not worth
keeping them around.
First things first- rename this directory! Once you have an idea for a name,
move one level up with cd ..
and run mv python-p3-cli-project-template <new-directory-name>
to change its name.
Note:
mv
actually stands for "move", but your computer interprets this rename as a move from a directory with the old name to a directory with a new name.
cd
back into your new directory and run git init
to create a local git
repository. Add all of your local files to version control with git add --all
,
then commit them with git commit -m'initial commit'
. (You can change the
message here- this one is just a common choice.)
Navigate to GitHub. In the upper-right corner of the page, click on the "+" dropdown menu, then select "New repository". Enter the name of your local repo, choose whether you would like it to be public or private, make sure "Initialize this repository with a README" is unchecked (you already have one), then click "Create repository".
Head back to the command line and enter git remote add <project name> <github url>
. This will map the remote repository to your local repository. Finally,
push your first commit with git push -u origin main
.
Your project is now version-controlled locally and online. This will allow you to create different versions of your project and pick up your work on a different machine if the need arises.
You might have noticed in the file structure- there's already a Pipfile! That being said, we haven't put much in there- just Python version 3.8 and ipdb.
Install any dependencies you know you'll need for your project, like SQLAlchemy and Alembic, before you begin. You can do this straight from the command line:
$ pipenv install sqlalchemy alembic
From here, you should run your second commit:
$ git add Pipfile Pipfile.lock
$ git commit -m'add sqlalchemy and alembic to pipenv'
$ git push
Now that your environment is set up, run pipenv shell
to enter it.
Once you're in your environment, you can start development wherever you'd like. We think it's easiest to start with setting up your database.
cd
into the lib/db
directory, then run alembic init migrations
to set up
Alembic. Modify line 58 in alembic.ini
to point to the database you intend to
create, then replace line 21 in migrations/env.py
with the following:
from models import Base
target_metadata = Base.metadata
We haven't created our Base
or any models just yet, but we know where they're
going to be. Navigate to models.py
and start creating those models. Remember
to regularly run alembic revision --autogenerate -m'<descriptive message>'
and
alembic upgrade head
to track your modifications to the database and create
checkpoints in case you ever need to roll those modifications back.
If you want to seed your database, now would be a great time to write out your
seed.py
script and run it to generate some test data. You may want to use
Pipenv to install Faker to save you some time.
A CLI is, simply put, an interactive script. You can run it with python cli.py
or include the shebang and make it executable with chmod +x
. It will ask for
input, do some work, and accomplish some sort of task by the end.
Past that, CLIs can be whatever you'd like. An inventory navigator? A checkout station for a restaurant? A choose-your-adventure video game? Absolutely!
Here's what all of these things have in common (if done well): a number of
import
statements (usually a lot of import statements), an if __name__ == "__main__"
block, and a number of function calls inside of that block. These
functions should be kept in other modules (ideally not just helpers.py
)
There will likely be some print()
statements in your CLI script to let the
user know what's going on, but most of these can be placed in functions in
other modules that are grouped with others that carry out similar tasks. You'll
see some variable definitions, object initializations, and control flow
operators (especially if/else
blocks and while
loops) as well. When your
project is done, your cli.py
file might look like this:
from helpers import (
function_1, function_2,
function_3, function_4,
function_5, function_6,
function_7, function_8,
function_9, function_10
)
if __name__ == '__main__':
print('Welcome to my CLI!')
function_1()
x = 0
while not x:
x = function_2(x)
if x < 0:
y = function_3(x)
else:
y = function_4(x)
z = function_5(y)
z = function_6(z)
z = function_7(z)
z = function_8(z)
function_9(z)
function_10(x, y, z)
print('Thanks for using my CLI')
README.md
is a Markdown file that describes your project. These files can be
used in many different ways- you may have noticed that we use them to generate
entire Canvas lessons- but they're most commonly used as homepages for online
Git repositories. When you develop something that you want other people to
use, you need to have a README.
Markdown is not a language that we cover in Flatiron's Software Engineering curriculum, but it's not a particularly difficult language to learn (if you've ever left a comment on Reddit, you might already know the basics). Refer to the cheat sheet in this lesson's resources for a basic guide to Markdown.
This README should serve as a template for your own- go through the important files in your project and describe what they do. Each file that you edit (you can ignore your Alembic files) should get at least a paragraph. Each function should get a small blurb.
You should descibe your actual CLI script first, and with a good level of detail. The rest should be ordered by importance to the user. (Probably functions next, then models.)
Screenshots and links to resources that you used throughout are also useful to users and collaborators, but a little more syntactically complicated. Only add these in if you're feeling comfortable with Markdown.
A lot of work goes into a good CLI, but it all relies on concepts that you've practiced quite a bit by now. Hopefully this template and guide will get you off to a good start with your Phase 3 Project.
Happy coding!