Working Ninja
2017-08-27T08:56:34

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')
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.setLevel(logging.INFO)

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

More examples and configurations: https://docs.python.org/2.7/library/logging.html

2017-08-27T08:44:20

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:
https://www.softwarecollections.org/en/scls/rhscl/python27/

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

import sys
sys.path.insert(0,'/path/to/project')
sys.path.insert(0,'/path/to/project/env/lib/python2.7/site-packages')

Lastly, call the script via Cron:

cat /path/to/project/script.py | scl enable python27 python
2017-08-24T21:01:28

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.

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

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

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

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

Source: https://docs.djangoproject.com/en/stable/topics/db/managers/

2017-08-24T07:47:57
# Simple List
', '.join([author.name for author in authors])

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

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

2017-05-29T10:58:45

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 =)

2017-05-02T17:37:37

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

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 = requests.post()
    r.json()['id']

Source: https://docs.python.org/dev/library/unittest.mock.htmll#unittest.mock.NonCallableMock

2017-04-03T20:16:40
from sqlalchemy.sql import text
from sqlalchemy import create_engine

import secrets


engine = create_engine(
    'mssql+pyodbc://{}:{}@MSSQL'.format(
        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:
https://github.com/mkleehammer/pyodbc/wiki/Connecting-to-SQL-Server-from-RHEL-or-Centos

Connecting to Microsoft SQL Server with pyodbc:
http://docs.sqlalchemy.org/en/latest/dialects/mssql.html#dialect-mssql-pyodbc-connect

2017-03-23T17:22:08

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

or

wc -l **/*.py

Source: http://stackoverflow.com/questions/1358540/how-to-count-all-the-lines-of-code-in-a-directory-recursively#1358573

2017-02-16T15:41:13
#!/usr/bin/python
import sys


try: 
    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/hex2rgb.py"

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
2017-02-10T16:39:53

Somehow, somewhere, something happened to my migrations. It had been a few months since I had edited my models.py 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:

./manage.py migrate --fake <app-name> zero
rm -rf <app-name>/migrations
./manage.py makemigrations <app-name>
./manage.py 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.

Source: https://stackoverflow.com/questions/23755523/how-to-reset-migrations-in-django-1-7