Moving out code

Sun 30 October 2016 by David Hontecillas

I have "monolith" django application for my website Katagatame.com. It is a very low traffic website at the moment, and given that I am the only developer, it is not something that I'm not going to change right now. (I can live with the drawbacks of everything running in a single server instance).

A monolith does not mean having a complete mess in the code. Actually, after identifying some reusable code I want to move that code out to a private library, so I can easily reuse it for other projects.

I do not wat to factor out a django app but simply a python library. Since it is going to be a private library I want to install from a git repo using pip.

Install from a git repo

The simplest way of all is getting the master branch of your repository:

pip install git+ssh://git@bitbucket.org/dhontecillas/rankedcompos.git

In the root directory you will need to have a setup.py file with information about your package:

from setuptools import setup

setup(name='rankedcompos',
      version='0.1',
      description='Package to generate competition brackets',
      url='https://dhontecillas@bitbucket.com/dhontecillas/rankedcompos.git',
      author='David Hontecillas',
      author_email='dhontecillas@gmail.com',
      license='MIT',
      packages=['rankedcompos'],
      zip_safe=False)

and you can check what you have installed in your virtual environment:

[your_virtualenvionment_dir]/lib/python2.7/site-packages/rankedcompos

and the egg information about it

egg info for checked out git

My PKG-INFO contains:

Metadata-Version: 1.0
Name: rankedcompos
Version: 0.1
Summary: Package to generate competition brackets
Home-page: https://dhontecillas@bitbucket.com/dhontecillas/rankedcompos.git
Author: David Hontecillas
Author-email: dhontecillas@gmail.com
License: MIT
Description: UNKNOWN
Platform: UNKNOWN

and if we list the intalled files, we will find that pip already precompiled the .pyc for us.

WIP repository

If we expect to do some work on the external (or separate) package, we can provide the editable flag, that will install the source in another place as source.

Lets give it a try! uninstall rankedcompos

Uninstall your package

pip uninstall rankedcompos
(venv)dhontecillas@devdebian:~/prg/sandbox/piptest$ pip uninstall rankedcompos
Uninstalling rankedcompos:
/home/dhontecillas/prg/sandbox/piptest/venv/lib/python2.7/site-packages/rankedcompos-0.1-py2.7.egg-info
/home/dhontecillas/prg/sandbox/piptest/venv/lib/python2.7/site-packages/rankedcompos/__init__.py
/home/dhontecillas/prg/sandbox/piptest/venv/lib/python2.7/site-packages/rankedcompos/__init__.pyc
/home/dhontecillas/prg/sandbox/piptest/venv/lib/python2.7/site-packages/rankedcompos/brackets.py
/home/dhontecillas/prg/sandbox/piptest/venv/lib/python2.7/site-packages/rankedcompos/brackets.pyc
/home/dhontecillas/prg/sandbox/piptest/venv/lib/python2.7/site-packages/rankedcompos/compokeys.py
/home/dhontecillas/prg/sandbox/piptest/venv/lib/python2.7/site-packages/rankedcompos/compokeys.pyc
/home/dhontecillas/prg/sandbox/piptest/venv/lib/python2.7/site-packages/rankedcompos/elorating.py
/home/dhontecillas/prg/sandbox/piptest/venv/lib/python2.7/site-packages/rankedcompos/elorating.pyc
/home/dhontecillas/prg/sandbox/piptest/venv/lib/python2.7/site-packages/rankedcompos/genkeys.py
/home/dhontecillas/prg/sandbox/piptest/venv/lib/python2.7/site-packages/rankedcompos/genkeys.pyc
/home/dhontecillas/prg/sandbox/piptest/venv/lib/python2.7/site-packages/rankedcompos/seedbrackets.py
/home/dhontecillas/prg/sandbox/piptest/venv/lib/python2.7/site-packages/rankedcompos/seedbrackets.pyc
/home/dhontecillas/prg/sandbox/piptest/venv/lib/python2.7/site-packages/rankedcompos/superteam.py
/home/dhontecillas/prg/sandbox/piptest/venv/lib/python2.7/site-packages/rankedcompos/superteam.pyc
/home/dhontecillas/prg/sandbox/piptest/venv/lib/python2.7/site-packages/rankedcompos/teambrackets.py
/home/dhontecillas/prg/sandbox/piptest/venv/lib/python2.7/site-packages/rankedcompos/teambrackets.pyc
/home/dhontecillas/prg/sandbox/piptest/venv/lib/python2.7/site-packages/rankedcompos/tests.py
/home/dhontecillas/prg/sandbox/piptest/venv/lib/python2.7/site-packages/rankedcompos/tests.pyc
Proceed (y/n)? y
Successfully uninstalled rankedcompos

uninstallin the repo code

Install with the editable flag

This time to use the -e (editable) flag, you must specify the egg name you want to use at the end of the git url.

pip install -e git+ssh://git@bitbucket.org/dhontecillas/rankedcompos.git#egg=YourEggName

And you will find that this time pip does installs it under your virtualenv/src directory instead of virtualenv/lib/python2.7/site-packages. The egg parameter that you provide in the url is the actual directory name that will be created under the src directory.

Also, the egg info dir is in the same base directory that your source code (instead of beeing in sibling directory), and it is an actual git clone of repo (instead of a bare checkout of source files that we previously had).

And a link under the /lib/python2.7/site-packages is created to point to that egg info dir under the src/YourEggName.

This way you can work in the git repo, make updates to the source code, commits, etc .. and you won't have to update the package every time.

Actually the point of using the -e flag makes more sense if instead of clonning from a remote repository, you give it the path to your local repo:

git clone git@bitbucket.org:dhontecillas/rankedcompos.git my_ranked_compos
pip install -e ./my_ranked_compos

This way you can develop in the package, while using it from your virtualenvironment. (Is kind of having a git submodule, but at the "package level").

Updating the package

The point is, how do we manage to get an update of the package ? First lets remove the editable package, performing a pip uninstall rankedcompos you wil find that only the link to the /venv/src that was created for the egg is removed. Now, you must delete by hand the repo that you have there (Unless it points to your local git repo).

We can pass wich branch, tag, or commit we want to checkout:

In order to upgrade the package is not enough to use the installed name, since it does not hold any reference to the original git repository, but the good part is that you do not need to change the version inside the setup.py file in order to get the latest version

pip install --upgrade git+ssh://git@bitbucket.org/dhontecillas/rankedcompos.git@v0.1

You only have to remember when doing a pip freeze to change your package name and version to the real url that you used.

Also, tag every new update accordingly with a different version number so it can be updated without the need of using the --upgrade flag.

References

There is the Python Packaging User Guide that has a complete explanation of how to package your libraries.

Stack overflow pip install from private git repo