If thinking of making a CLI tool, consider using Python with click
. It is very fast and will make your life easier. It is probably the most straightforward way to automate tasks.
This script removes an enormous headache of making blog posts. As I already tend to take notes using the Jupyter Notebook, it makes it very easy to blog regularly.
There are a number of good libraries that make making CLI apps with Python easy. I am personally a big fan of click
as it seems to be the quickest way to get running. I have a short CLI available that automates my blog posting workflow here.
Here is the heart of pelican_autopost
. This little code already makes all of the necessary documentation, prompts, default values, and arguments.
import click
BLOG_DIR = '~/blog'
@click.command()
@click.option('--blog-dir', default=BLOG_DIR)
@click.option('--notebook-path', prompt='Enter the full notebook path',
help='files must be''located in `blog_dir`')
@click.option('--title', prompt='enter the title. Must be unique', default=None)
@click.option('--tags', prompt='enter a tag. You may enter more than one via',
multiple=True)
@click.option('--category', default=None)
def _main(blog_dir, notebook_path, title, tags, category):
"""
Simple program that takes the directory of a notebook
(use `greadlink -f file.ipynb | pbcopy`)
and other parameters and then publishes it to my pelican blog.
Examples
----
./pelican_auto_post.py --tags *Nix --tags CLI --title sqlite3
Enter the full notebook path: /Users/Will/Devel/blog_posts/sqlite3_CLI.ipynb
"""
if not title:
title = os.path.splitext(notebook_path)[0]
make_md(blog_dir, title, tags, category, notebook_path)
copy_notebook(notebook_path, blog_dir, title)
publish(blog_dir)
Now that we have the script, we can easily run it from anywhere by performing the following steps:
~/scipts
. Move your script to here.PATH
environmental variable. For OSX this is ~/.bash_profile
#!/usr/bin/env python3
Executing bash scripts from Python can be tricky. The Github describes how I did it but the most robust way to do this seems to be to execute the data directly from python like this:
from subprocess import call
with open('~/scripts/script_name.sh'):
script = file.read()
rc = call(script, shell=True)
Make sure that you only run this with trusted code that oyu are feeding it yourself. Otherwise it poses a security issue. An alterantive option would be to santize the file in Python before using subprocess.call
on it.
If the CLI is quite small, often times the best test is just going to be the script itself. I recommend to only test to prevent the things that can cause problems (accidently overwriting or deleting files). In the pelican autopost tool, for example, the only test I feel helped is the one that insures that the markdown files won’t be overwritten because this could cause problems if there were to be two blog posts of the same title.
Written on October 21st , 2015 by Will Sorenson