= Python =
Python is a programming language that lets you work more quickly and integrate your systems more effectively. 

Links:
 * [[http://docs.python.org/2/library/]]
 * [[http://www.tutorialspoint.com/python/]]

== UTF-8 ==
At the start of source code files:
{{{#!highlight python
# -*- coding: utf-8 -*-
print u"Olá mundo" # hello world in portuguese
}}}

Letter '''á''' is encoded as hexadecimal '''0xC3A1''' in UTF-8 and as '''0x00E1''' in UTF-16.
[[http://www.fileformat.info/info/unicode/char/e1/index.htm]]

Letter '''ú''' is encoded  as hexadecimal '''0xC3BA''' in UTF-8, as '''0x00FA''' in UTF-16 and as '''0xFA''' in latin-1/ISO8859-1/CP-1252.

{{{#!highlight python
#utf-8 data
utf81 ='\xc3\xba' 
# convert from utf-8 to unicode
unic = utf81.decode('utf-8') 

for c in unic:
    print '%04X'%(ord(c))
# convert from unicode to latin1/ISO8859-1 CP-1252
lat1=unic.encode('latin1') 
for c in lat1:
    print '%02X'%(ord(c))
}}}

== Utf-8 and Unicode ==
{{{#!highlight python
utf81='\xe1\xb7\x97' #utf-8 data

unic = utf81.decode('utf-8') #converts from utf-8 to unicode (utf-16)
for c in unic:
    print '%04X'%(ord(c))
type(unic) # unicode, 2 bytes per char
type(utf81) # str, 1 bytes per char
}}}

== Time and date ==
{{{#!highlight python
import time
# get seconds since epoch until now in UTC to a string year-month-dayThour:minute:second
strutc = time.strftime('%Y-%m-%dT%H:%M:%S', time.gmtime() ) 
# get seconds since epoch until now  in localtime to a string  year-month-dayThour:minute:second
strlocal = time.strftime('%Y-%m-%dT%H:%M:%S', time.localtime() ) 
# number seconds since epoch
nrSeconds = time.mktime(time.gmtime())
nrSeconds = time.time() #usually is UTC on all OS
# from timestamp to string date
import datetime
print(datetime.datetime.fromtimestamp(1284101485).strftime('%Y-%m-%d %H:%M:%S'))
#
def toUTCDateStr(timestamp):
    return datetime.datetime.utcfromtimestamp( timestamp ).strftime('%Y-%m-%d %H:%M:%S ')
# timedelta
import datetime
x=datetime.datetime.fromtimestamp(1284101485)
nowx=datetime.datetime.now()                    
ts=(nowx-x).total_seconds()
print int(ts)
}}}

== Write and reading data for a plist file ==
A plist file stores data in XML format.

{{{#!highlight python
import plistlib
value = [{'key1':123,'key2':'asdf'},{'keyx1':'testing','keyz1':'yup'}]
# save value in plist file
plistlib.writePlist(value,'/tmp/plist1.plist')
o=plistlib.readPlist('/tmp/plist1.plist')
print o
}}}

Content of the file '''/tmp/plist1.plist'''
{{{#!highlight xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
        <dict>
                <key>key1</key>
                <integer>123</integer>
                <key>key2</key>
                <string>asdf</string>
        </dict>
        <dict>
                <key>keyx1</key>
                <string>testing</string>
                <key>keyz1</key>
                <string>yup</string>
        </dict>
</array>
</plist>
}}}

== Threading ==

{{{#!highlight python
#!/usr/bin/python
# timestable.py
# calculates the times table in concurrency
import threading
import time

class TimesTable (threading.Thread):
    def __init__(self, timesTable):
        threading.Thread.__init__(self) #required
        self.timeTable = timesTable
        self.count = 1
    def run(self):
        loop=True
        while loop:
            time.sleep(1) #sleep for 1 second
            result=self.timeTable * self.count
            print "%d*%d=%d"%(self.timeTable,self.count,result)
            if self.count<10:
	        self.count = self.count+1
	    else:
	        self.count=1

# create threads
timesTable2 = TimesTable(2)
timesTable5 = TimesTable(7)

# start the threads
timesTable2.start()
timesTable5.start()
}}}

== unit tests ==
{{{#!highlight python
#filename: unitTest.py
#Run tests: python unitTest.py
#Should fail on testAdd2
import unittest

class SimpleTestCase(unittest.TestCase):
    def setUp(self):
        self.res=4

    def tearDown(self):
        self.res=0

    def testAdd1(self):
        res=2+2
        self.assertEqual(self.res,res,'')       

    def testAdd2(self):
        res=2+3
        self.assertEqual(self.res,res,'')       

    def testAdd3(self):
        res=2+3
        self.assertNotEqual(self.res,res,'')       

if __name__ == '__main__':
    unittest.main()
}}}

== cython ==
Installation:
 * su
 * cd /tmp
 * wget http://cython.org/release/Cython-0.19.1.tar.gz
 * tar xvzf Cython-0.19.1.tar.gz 
 * cd Cython-0.19.1
 * python setup.py build
 * python setup.py install

== pymssql ==
Requires cython.
Installation:
 * su
 * cd /tmp
 * wget [[http://pymssql.googlecode.com/files/pymssql-2.0.0b1-dev-20111019.tar.gz]]
 * tar xvvzf pymssql-2.0.0b1-dev-20111019.tar.gz
 * cd pymssql-2.0.0b1-dev-20111019
 * python setup.py build
 * python setup.py install
 * python
 * import pymssql

== pywhois ==
Python module for retrieving WHOIS information of domains [[http://code.google.com/p/pywhois/]].

Fetch code with mercurial:
 * cd /tmp
 * hg clone https://code.google.com/p/pywhois/
 * cd pywhois
 * python setup.py build
 * python setup.py install

== Syntax highlighting on Vim for wsgi ==
Edit ~./.vimrc:
{{{#!highlight bash 
syntax on
filetype on
au BufNewFile,BufRead *.wsgi set filetype=python
}}}

== Get file modification time ==
{{{#!highlight python
import os
nrSeconds=os.path.getmtime('/folder/file') # unix epoch, nr secs since 1970-01-01 00:00:00
}}}

== Kill process with PID ==
{{{#!highlight python
import os
import signal
os.kill(pid,signal.SIGTERM) 
}}}

== Log message to /var/log/messages or /var/log/syslog ==
{{{#!highlight python
import syslog
syslog.syslog(syslog.LOG_INFO,'message to syslog')
}}}

{{{#!highlight python
import syslog

syslog.syslog(syslog.LOG_DEBUG,'DEBUG')
syslog.syslog(syslog.LOG_INFO,'INFO')
syslog.syslog(syslog.LOG_WARNING,'WARNING')
syslog.syslog(syslog.LOG_ERR,'ERR')
syslog.syslog(syslog.LOG_CRIT,'CRIT')
}}}

||OS||File||Logged levels||
||Slack64 14||/var/log/messages|| INFO ||
||Slack64 14||/var/log/syslog|| WARNING ERR CRIT ||
||CentOS 6.4||/var/log/messages|| INFO WARNING ERR CRIT ||
||Ubuntu 12.04 Precise||/var/log/syslog||DEBUG INFO WARNING ERR CRIT ||
||Debian 7.0 Wheezy||/var/log/syslog||DEBUG INFO WARNING ERR CRIT ||

== Simple process monitor ==
{{{#!highlight python
# example service, dummyService.py
import time
while True:
    try:
        f=open('filex.log','wb')
        f.write('%f'%(time.time()))
        f.close() 
        time.sleep(5)
    except KeyboardInterrupt:
        quit()
}}}

{{{#!highlight python
#service monitor.py
# * * * * * /usr/bin/python /home/vitor/svc/monitor.py
import os
import syslog
import subprocess

if __name__=="__main__":
    files = os.listdir('/proc')
    script="dummyService.py"
    prefix="dummyService:"

    svcRunning=False

    for file in files:

        if file.isdigit():
            cmdline = open('/proc/%s/cmdline'%(file),'r').read()
            proc = "%s %s "%(file,cmdline)

            if script  in proc :
                svcRunning=True

    if svcRunning==False:
        syslog.syslog(syslog.LOG_INFO,'%s process created '%(prefix) )
        subprocess.Popen(['/usr/bin/python','dummyService.py'],cwd='/home/userx/svc')
}}}

== Read URL content ==
{{{#!highlight python
import urllib2
r=urllib2.urlopen('http://www.sapo.pt')
resp=r.read()
print resp
}}}

== Windows service ==
Install http://sourceforge.net/projects/pywin32/files/pywin32/Build%20218/pywin32-218.win32-py2.5.exe/download for Python 2.5 for Windows.

Adapted from http://ryrobes.com/python/running-python-scripts-as-a-windows-service/
{{{#!highlight python
# C:\cmt\test>python testWinSvc.py install
# C:\cmt\test>python testWinSvc.py start
# C:\cmt\test>python testWinSvc.py stop
# C:\cmt\test>python testWinSvc.py remove
# C:\cmt\test>service.msc
import win32service
import win32serviceutil
import win32api
import win32con
import win32event
import win32evtlogutil
import os, sys, string, time

class aservice(win32serviceutil.ServiceFramework):
   _svc_name_ = "MyServiceShortName"
   _svc_display_name_ = "My Service Long Fancy Name!"
   _svc_description_ = "THis is what my crazy little service does - aka a DESCRIPTION! WHoa!"
         
   def __init__(self, args):
           win32serviceutil.ServiceFramework.__init__(self, args)
           self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)           

   def SvcStop(self):
           self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
           win32event.SetEvent(self.hWaitStop)                    
         
   def SvcDoRun(self):
      import servicemanager      
      servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,servicemanager.PYS_SERVICE_STARTED,(self._svc_name_, ''))       
      self.timeout = 1000     #1 second
      # This is how long the service will wait to run / refresh itself (see script below)

      while 1:
         # Wait for service stop signal, if I timeout, loop again
         rc = win32event.WaitForSingleObject(self.hWaitStop, self.timeout)
         # Check to see if self.hWaitStop happened
         if rc == win32event.WAIT_OBJECT_0:
            # Stop signal encountered
            servicemanager.LogInfoMsg("SomeShortNameVersion - STOPPED!")  #For Event Log
            break
         else:
                 try:
                     handle = open('c:/windows/temp/outx1.txt', "a")
                     handle.write('%s \n' % ('tst svc'))
                     handle.close()
                 except:
                     pass



def ctrlHandler(ctrlType):
   return True
                  
if __name__ == '__main__':   
   win32api.SetConsoleCtrlHandler(ctrlHandler, True)   
   win32serviceutil.HandleCommandLine(aservice)
}}}

== Logging ==
Adapted from http://docs.python.org/2/howto/logging-cookbook.html#logging-to-multiple-destinations

{{{#!highlight python
import logging

logging.basicConfig(level=logging.DEBUG, \
    format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s', \
    datefmt='%Y-%m-%d %H:%M:%S %z', \
    filename='/tmp/myapp.log', \
    filemode='a')
#log to console
console = logging.StreamHandler()
console.setLevel(logging.INFO)
formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
console.setFormatter(formatter)
logging.getLogger('').addHandler(console)
logging.info('Jackdaws love my big sphinx of quartz.')
#other loggers
logger1 = logging.getLogger('myapp.area1')
logger2 = logging.getLogger(__name__)
logger1.debug('Quick zephyrs blow, vexing daft Jim.')
logger1.info('How quickly daft jumping zebras vex.')
logger2.warning('Jail zesty vixen who grabbed pay from quack.')
logger2.error('The five boxing wizards jump quickly.')
}}}


Copied from http://docs.python.org/2/howto/logging-cookbook.html#configuration-server-example
Logging configurable on runtime, receiving new parameters by socket

Server:
{{{#!highlight python
import logging
import logging.config
import time
import os

# read initial config file
logging.config.fileConfig('logging.conf')

# create and start listener on port 9999
t = logging.config.listen(9999)
t.start()

logger = logging.getLogger('simpleExample')

try:
    # loop through logging calls to see the difference
    # new configurations make, until Ctrl+C is pressed
    while True:
        logger.debug('debug message')
        logger.info('info message')
        logger.warn('warn message')
        logger.error('error message')
        logger.critical('critical message')
        time.sleep(5)
except KeyboardInterrupt:
    # cleanup
    logging.config.stopListening()
    t.join()
}}}

Client:
{{{#!highlight python
#!/usr/bin/env python
import socket, sys, struct

with open(sys.argv[1], 'rb') as f:
    data_to_send = f.read()

HOST = 'localhost'
PORT = 9999
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print('connecting...')
s.connect((HOST, PORT))
print('sending config...')
s.send(struct.pack('>L', len(data_to_send)))
s.send(data_to_send)
s.close()
print('complete')
}}}

== Logging with date rotation and email ==
{{{#!highlight python
import logging
from logging.handlers import TimedRotatingFileHandler
from logging.handlers import SMTPHandler

class Logger(object):
    def __init__(self):
        loggerName='appx'
        logFormatter = logging.Formatter('[%(asctime)s %(name)-12s %(levelname)-8s] %(message)s',datefmt='%Y-%m-%d %H:%M:%S %z')
        
        rotatingLogHandler = TimedRotatingFileHandler('%s.log'%(loggerName),when='midnight',utc=True)
        rotatingLogHandler.setFormatter(logFormatter)
        rotatingLogHandler.setLevel(logging.DEBUG)

        smtpLogHandler = SMTPHandler(mailhost='hostx.com', fromaddr='mail@hostx.com', toaddrs='dest@hostx.com', subject=loggerName, \
            credentials=('accountx','12345678'), secure=None)
        smtpLogHandler.setFormatter(logFormatter)
        smtpLogHandler.setLevel(logging.WARNING)
                        
        self.logger = logging.getLogger(loggerName)
        self.logger.addHandler(rotatingLogHandler)
        self.logger.addHandler(smtpLogHandler)
        self.logger.setLevel(logging.DEBUG)
        
    def debug(self,m):
        self.logger.debug(m)

    def info(self,m):
        self.logger.info(m)

    def warning(self,m):
        self.logger.warning(m)
        
    def error(self,m):
        self.logger.error(m)
        
    def critical(self,m):
        self.logger.critical(m)

}}}

== pytz - World Timezone Definitions for Python ==
{{{#!highlight python

import pytz
import datetime

#fmt = '%Y-%m-%d %H:%M:%S %Z%z'
london=pytz.timezone('Europe/London')
lisbon=pytz.timezone('Europe/Lisbon')
paris  =pytz.timezone('Europe/Paris')
utc = pytz.timezone('UTC')
berlin = pytz.timezone('Europe/Berlin')

print
dtx = datetime.datetime(2002, 12, 27, 12, 0, 0,tzinfo=utc ) 
print 
print 'UTC    ' , dtx
print 'London ',dtx.astimezone(london)
print 'Lisbon ',dtx.astimezone(lisbon)
print 'Paris  ',dtx.astimezone(paris)
print 'Berlin ',dtx.astimezone(berlin)


print
dty = datetime.datetime(2002, 8, 27, 13, 0, 0,tzinfo=utc ) 
print 'UTC    ',dty
print 'London ',dty.astimezone(london)
print 'Lisbon ',dty.astimezone(lisbon)
print 'Paris  ',dty.astimezone(paris)
print 'Berlin ',dty.astimezone(berlin)
}}}

== Sort example ==
{{{#!highlight python
class Acme(object):
    def __init__(self,valuex):
        self.valuex=valuex

    def __cmp__(self, other):
        if self.valuex==other.valuex:
            return 0
        if self.valuex>other.valuex:
            return 1
        if self.valuex<other.valuex:
            return -1

    def __repr__(self):
        return self.valuex

if __name__=='__main__':
    listx=[]
    listx.append( Acme('C') )
    listx.append( Acme('A') )
    listx.append( Acme('Z') )
    print 'original:',listx
    print 'sorted asc:',sorted(listx,reverse=False)
    print 'sorted desc:',sorted(listx,reverse=True)
    listx.sort()
    print 'sort:',listx
    listx.reverse()
    print 'reverse:',listx
}}}