Working Ninja

Here's how I set up logging where:

  • Log files rotate nightly (at midnight).
  • We keep 10 total log files (as history).
import logging
import os

# Set up logging
logger = logging.getLogger(__file__)
handler_kwargs = {
    'filename': os.path.join(base_dir, 'file.log'),
    'when': 'midnight',
    'backupCount': 10
handler = handlers.TimedRotatingFileHandler(**handler_kwargs)
formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')

# Now log something'Log something informative.')
logger.warning('Log a warning.')
logger.error('Log an error.')
logger.critical('Log a critical error.')

More examples and configurations:


Python 2.7 is not provided on CentOS 6 because Yum depends on Python 2.6. Simply installing 2.7 over 2.6 will break Yum. Thankfully, Red Hat provides us with an alternate installation method through their SCL project.

First, get Python 2.7 installed:

Next, add the project path to the top of the script:

import sys

Lastly, call the script via Cron:

cat /path/to/project/ | scl enable python27 python

Here's a custom manager for a class (Change) that gets all approved changes where "today's date" falls between the Change.start_date and Change.end_date.

import datetime
# Custom Change Manager that only pulls active, approved changes
class ApprovedChanges(models.Manager):
    def get_queryset(self):
        today =
        return super(ApprovedChanges, self).get_queryset().filter(

class Change(models.Model):
    approved_changes = ApprovedChanges()

In our view, we could then call all changes for "today" that have been approved:

def todays_changes(self):
   changes = Changes.approved_changes.all()


# Simple List
', '.join([ for author in authors])

# Django
', '.join([ for author in book.author_set.all()])

Both will output "Author Name, Author 2 Name, ..., Author x Name"


I just started my first Django project with Python 3 in earnest. One of the first things I have noticed is that reload isn't available by default from the Django shell. It needs to be imported:

>>> from importlib import reload
>>> reload(<module>)

This became a pretty tedious process and didn't always reload the module as expected. So, instead of reloading the shell and the module to run a command, I moved the commands that I was running into a custom Django management command. No more reloading =)


The following code allows us to monkey patch the json() method that is returned by

import requests
from mock import MagicMock

@mock.patch.object(requests, 'post')
def my_function(self, post):
    attrs = {'json.return_value': {'id': 1}}
    post.return_value = MagicMock(**attrs)

    r =


from sqlalchemy.sql import text
from sqlalchemy import create_engine

import secrets

engine = create_engine(
        secrets.username, secrets.password
conn = engine.connect()

s = text("SELECT * FROM users WHERE name = :name")
result = conn.execute(s, name=name).fetchall()
print result

For further information on installing and configuring unixODBC (requirement for pyodbc) on Linux:

Connecting to Microsoft SQL Server with pyodbc:


Here's a simple way to count lines of code via the command line that I recently used for a Django project:

find . -name '*.py' -not -path "*/migrations/*" | xargs wc -l


wc -l **/*.py


import sys

    hex_val = str(sys.argv[1])
except Exception as e:
    sys.exit('Please provide a hex code as an argument (e.g. hex2rgb 333333).')

r = int(hex_val[0:2], 16)
g = int(hex_val[2:4], 16)
b = int(hex_val[4:6], 16)

print('{}, {}, {}'.format(r, g, b))

Append your ~/.bash_aliases with:

alias hex2rgb="~/bin/"

Load the new alias:

$ source ~/.bash_aliases

Now we're able to convert Hex to RGB from the command line:

$ hex2rgb e1e1e1
255, 255, 255

Somehow, somewhere, something happened to my migrations. It had been a few months since I had edited my file and out of the blue I ended up with an issue adding an additional field to a model. I search around Stack Overflow and found a great answer that resolves this (hopefully it doesn't happen to you!). Here's what the recommendation was:

./ migrate --fake <app-name> zero
rm -rf <app-name>/migrations
./ makemigrations <app-name>
./ migrate --fake <app-name>

If you ran into this issue at the same time that I did (when adding a new field to a model), comment out the field you just added before you run any of the above commands (also comment out any additional new changes you may have made). If you don't, the last migrate --fake will include your new field/changes without generating a new migration file for it.