Blog Tags: 

pyproject-pub: A simple Python project template

I hate repeating myself. It's boring. Life is too short. Like any self respecting hacker I will go out of my way to avoid it, even when I suspect it would cost me more to automate something away than to just do it by hand.

On the other hand, doing stuff I've done before by hand is no fun, while writing scripts is fun. Even when it does take longer, time is relative, or so Einstein said.

Plus, everyone knows you're much likely to make mistakes doing mind numbingly stuff, so factor that into the cost comparison. Also, doing stupid stuff over and over again makes you stupid. I'm pretty sure I read that somewhere but I might just be making it up.

So anyhow, I like writing scripts to automate stuff I'd rather not do over and over again by hand. But the zinger is that writing a new script can itself involve repetitive tasks. I'll need to create an installation routine, Debian packaging, Git repository, etc.

To avoid the catch-22, you'll want to automate that as well, which is exactly what I created pyproject-pub for. The -pub stands for public. pyproject-pub is actually a simpler, stripped down implementation of pyproject, a former Python program template I used privately which is about 4 years older and has a ton of additional complexity and a tricky set of dependencies, including one that's circular. Thankfully, most of my public projects don't need all my usual bells and whistles, hence the reboot.

You can find the latest branch of pyproject-pub on GitHub. Here's the documentation:

Why does this exist?

Minimize friction in creating a new Python program.


  1. Auto-creates Git repository.
  2. Local installation via "make install" target
  3. Debian packaging support.
  4. Supports programs with a single executable command (I.e., foo) or with multiple executable commands (example-foo, example-bar).


  1. Initializing a new project:

    cp -a pyproject-pub myproject
    cd myproject
    make init

Installation paths

$(prefix)/lib: where Python files go. $(prefix)/bin: where symbolic links to executable commands in lib/ go. $(prefix)/share/contrib: where shared contrib stuff goes.

$(prefix) defaults to...

/usr/local: when installed locally with make install 
/usr: when installed from the built Debian package

A program with a executable command

make init creates an Python file under $(yourprojectname).py containing cli stub code. Just implement your command there. When installed you will be able to execute $(yourprojectname):

cp -a pyproject-pub mytest
cd mytest
make init

# edit your program

make install

A program with multiple executable commands

Create multiple executable Python files:

cp -a pyproject-pub mytest
cd mytest
make init

make install

# symlinks in /usr/local/bin


Jeremy Davis's picture

I can use either in TurnKey (i.e. 'git-clone' or 'git clone') both work fine. But I recall working in Raspbian and by default it would only accept 'git clone'...

It must be some setting the TurnKey guys include somewhere. I'll see if I can hunt it down and get back to you. Although probably not making it require that might be a better long term option.

Jeremy Davis's picture

It's done by adding /usr/lib/git-core to $PATH. TurnKey implements it like this (as well as some handy aliases).

Regardless Alon has just committed a fix so it doesn't rely on them anyway.



Add new comment