Blog Archives

How to compile pycrypto 2.4.1 (python 3.2.2 for Windows 7 x64)

This note is a variation of note that talks about compiling cx_Oracle module for python 3.2 (64-bit), but this time around I wanted to try out pycrypto module v2.4.1 that supports python 3. Let me say that I first tried to build pycrypto with MinGW using TLDR experimental installation package for Windows x64. Making long story short, it was a bummer (I hit several errors that I didn’t know how to resolve), I didn’t even try if 32-bit module could be compiled with MinGW. Anyway, I believe sticking with VC 2008 and bulky SDK (over 5GB of installed SW!) is inevitable, at least for me. Here’re the steps that I followed….

My target platform for the pycrypto build was Windows 7 Professional x64 (SP1) with 64-bit python 3.2.2.

1) Download and install Visual Studio Express 2008 SP1 from MS site

It’s mandatory to build python modules with VC 2008, because this is the compiler that was used
to build python 3.2. Note that I installed default components of Visual Studio 2008 in default location.

2) Because Visual Studio Express 2008 SP1 doesn’t ship with 64-bit compiler, download
and install Windows SDK for Windows 7 and .NET 3.5 SP1
.

Again, don’t be tempted to install newer Windows SDK for Windows 7 and .NET 4, it must be older SDK (released in 2009). I left all installation options at default.

3) Download and install 64-bit python 3.2.2

Ok, this is obvious step. :-)

4) Download pycrypto 2.4.1

After you download unzip pycrypto-2.4.1.tar.gz in some temporary directory, such as C:\Temp

5) Prepare command shell for 64-bit compiler:

Start -> Run

%comspec% /k ""C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin\vcvars64.bat""

Then enter the following on the command line:

SET PATH=C:\PYTHON32;%PATH%

SET PYTHONHOME=C:\Python32\

cd C:\Temp\pycrypto-2.4.1

python setup.py build

python setup.py bdist_wininst

In dist directory you’ll find installation file:

pycrypto-2.4.1.win-amd64-py3.2.exe

After you install pycrypto, check that it works:

cmd> python
>>> import Crypto
>>> print(Crypto.__version__)
2.4.1

IronPython – working with Registry

Here is a code snippet that I wrote recently for IronPython, correcting some registry information that I put by mistake in our image that is used for cloning client PC’s. I’m sure PowerShell script would be even shorter and cleaner, but I had to come with some working code in a hurry.

# -*- coding: cp1250 -*-
# odbc_patch.py -- patching my shallowness
# AlesK.

__about__= "IronPython script // odbc_patch2.py by AlesK"

from Microsoft.Win32 import Registry

# -----------------------------------------------
# How to enumerate a node from ODBC.INI.
# Print System DSN names with SERVER key value if present
# (SERVER key is mandatory for MS ODBC for Oracle, MySQL ODBC,
# etc., but not for Oracle supplied driver!
# 
# For complete reference to Regirstry class refer to:
# msdn.microsoft.com/en-us/library/microsoft.win32.registry.aspx
# You can use:
# Registry.ClassesRoot|CurrentConfig|CurrentUser|
#          LocalMachine|PerformanceData|Users
# ------------------------------------------------
system_dsn = Registry.LocalMachine.OpenSubKey('Software\\ODBC\\ODBC.INI')

for dsn in system_dsn.GetSubKeyNames():
    dsn_key = system_dsn.OpenSubKey(dsn)
    server = dsn_key.GetValue('SERVER')
    # print only those DSN's that were created with MS ODBC)
    # and thus have SERVER defined
    if server is not None:
        print("DSN=" + dsn + " SERVER=" + str(server))

# ------------------------------------------------------
# How to read and change value in registry.
# Registry.GetValue
# Registry.SetValue
#
# The plot: by mistake I added MS at the end of SERVER variable
# for DSN's that are using MS ODBC driver. Instead of
# SERVER = ORAXMS I really want SERVER = ORAX, striping off MS.
# Candidates in my case are: ORAXMS, ORAYMS, ORAZMS.
# ------------------------------------------------------

odbc_dsn = ['ORAXMS','ORAYMS','ORAZMS']
odbc_node = "HKEY_LOCAL_MACHINE\\Software\\ODBC\\ODBC.INI"
odbc_key  = "SERVER"

for dsn in odbc_dsn:
    value = ''
    value = Registry.GetValue(odbc_node + '\\' + dsn, odbc_key, value)
    if value in odbc_dsn:
        Registry.SetValue(odbc_node + '\\' + dsn, odbc_key, dsn.strip('MS'))
        print("ODBC.INI: patched " + dsn + " SERVER=" + dsn +
              " to SERVER=" + dsn.strip('MS'))
    else:
        print("ODBC.INI: " + dsn + " - nothing to patch.")

Sample output:

C:\Scripts\IronPython\Registry>ipy odbc_patch2.py
DSN=ORAXMS SERVER=ORAXMS
DSN=ORAYMS SERVER=ORAYMS
DSN=ORAZMS SERVER=ORAZMS
DSN=ORA6MS SERVER=ORAT
ODBC.INI: patched ORAXMS SERVER=ORAXMS to SERVER=ORAX
ODBC.INI: patched ORAYMS SERVER=ORAYMS to SERVER=ORAY
ODBC.INI: patched ORAZMS SERVER=ORAZMS to SERVER=ORAZ

Wake-On-Lan with Python 3.x

In addition to PowerShell Wake-On-LAN script example I found example that works with python 3.x in ActiveState Code recipes collection:

#!/usr/bin/env python
 # wol.py
 # 
 # This module is from ActiveState Code Recipes:
 # http://code.activestate.com/recipes/358449-wake-on-lan/
 # and patched for Python 3 with:
 # http://code.activestate.com/recipes/577609-wake-on-lan-for-python-3/
 #
 # Example:
 # import wol
 # wol.wake_on_lan('70:F3:95:15:00:B5')
 #
import socket
import struct
 
def wake_on_lan(macaddress):
    """ Switches on remote computers using WOL. """
    
    # Check macaddress format and try to compensate
    if len(macaddress) == 12:
        pass
    elif len(macaddress) == 12 + 5:
        sep = macaddress[2]
        macaddress = macaddress.replace(sep,'')
    else:
        raise ValueError('Incorrect MAC address format')
        
        
    # Pad the synchronization stream
    data = b'FFFFFFFFFFFF' + (macaddress * 20).encode()
    send_data = b''
    
    # Split up the hex values in pack
    for i in range(0, len(data), 2):
        send_data += struct.pack('B', int(data[i: i + 2], 16))
    
    # Broadcast it to the LAN
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
    sock.sendto(send_data, ('255.255.255.255',7))

Python 3.2.1 on OEL 6.1

--
-- Installing python 3.2.1 on OEL 6.1 from source
--
$ sudo yum install tk-devel gdbm-devel
$ mkdir python
$ cd python
$ export http_proxy=acme.proxy.com:80
$ wget http://www.python.org/ftp/python/3.2.1/Python-3.2.1.tgz
$ tar xvzf Python-3.2.1.tgz
$ cd Python-3.2.1
$ ./configure --prefix=/opt/python3.2
$ make
$ make test
$ sudo make install
$ sudo ln -s /opt/python3.2/bin/python3.2 /usr/bin/python32
$ sudo ln -s /opt/python3.2/bin/idle3.2 /usr/bin/idle-python32

-- cx_Oracle is (of course) mandatory library 
$ mkdir cx_Oracle
$ cd cx_Oracle
$ wget http://prdownloads.sourceforge.net/cx-oracle/cx_Oracle-5.1.tar.gz?download
$ tar xvzf cx_Oracle-5.1.tar.gz
$ cd cx_Oracle-5.1
$ sudo -s
# . /u01/app/oracle/product/11.2.0/xe/bin/oracle_env.sh
# export LD_LIBRARY_PATH=$ORACLE_HOME/lib
# python32 setup.py build
# python32 setup.py install

-- lxml 2.3
-- libxml2 and libxslt1.1 libraries were already installed
-- on OEL 6.1, so it was as easy as downloading lxml from PyPI
-- and installing with:

$ tar xvzf lxml-2.3.tar.gz
$ cd lxml-2.3
$ python32 setup.py build
$ sudo python32 setup.py install

-- run test:
$ python32
>> from lxml import etree
>> print(etree.LXML_VERSION)
>> print(etree.LIBXML_VERSION)
>> print(etree.LIBXSLT_VERSION)

ASRock mini – Part 5.

Here are my notes about setting up python programming environment on my ASRock mini running Ubuntu 10.04 (32-bit), covering the latest and greatest Python 3.2, plus some third party libraries that I need for my work.

Fifth note in this series will cover:

  • how to install python 3.2.0 (32-bit) from source in alternate location
  • how to install cx_Oracle 5.0.4 from source
  • how to install PyYAML 3.09 from source
  • how to install lxml 2.3 from source
  • how to install PyQt 4.8.3 from source

PYTHON 3.2
Soon after my first failed attempt to compile python 3.2 on my Ubuntu 10.04 workstation, I realized that tk-dev package was missing on my system, causing IDLE to report the error:
IDLE can’t import Tkinter. Your Python may not be configured for Tk.

$ sudo apt-get install tk-dev

Then I proceeded with the python build:

$ mkdir python
$ cd python
$ mkdir python32
$ cd python32
$ wget http://www.python.org/ftp/python/3.2/Python-3.2.tgz
$ tar xvzf Python-3.2.tgz
$ cd Python-3.2
$ ./configure --prefix=/opt/python3.2
$ make
$ sudo make install
$ sudo ln -s /opt/python3.2/bin/python3.2 /usr/bin/python32
$ sudo ln -s /opt/python3.2/bin/idle3.2 /usr/bin/idle-python3.2

Now you can create launcher on your desktop that’ll point to /usr/bin/idle-python3.2.


THIRD PARTY LIBRARIES


cx_Oracle 5.0.4

Note! I’m using “full” Oracle 11g R2 client, not an instant client! For instant client refer to the BUILD document that ships with cx_Oracle library.


-- Download tar with the source from http://cx-oracle.sourceforge.net/
-- to ~/python/cx_Oracle, then proceed:
$ export ORACLE_HOME=/oracle/ora11
$ export LD_LIBRARY_PATH=/oracle/ora11/lib
$ cd ~/python/cx_Oracle
$ tar xvzf cx_Oracle-5.0.4.tar.gz
$ cd cx_Oracle-5.0.4
$ python32 setup.py build
$ sudo su - root
# export ORACLE_HOME=/oracle/ora11
# export LD_LIBRARY_PATH=/oracle/ora11/lib
# cd /home/alesk/python/cx_Oracle/cx_Oracle-5.0.4
# python32 setup.py install
# exit

Notice how I “sudo su – root” to root and set ORACLE_HOME and LD_LIBRARY_PATH variables, otherwise install will fail if you simply “sudo python32 setup.py install”, since root (usually) doesn’t have profile with environment variables related to Oracle installation.

Make a short test:

$ python32
Python 3.2 (r32:88445, Mar 16 2011, 19:42:11) 
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import cx_Oracle
>>> print(cx_Oracle.version)
5.0.4
>>> print(cx_Oracle.clientversion())
(11, 2, 0, 2, 0)

PyYAML 3.09


$ cd ~/python/PyYAML
$ wget http://pyyaml.org/download/pyyaml/PyYAML-3.09.tar.gz
$ tar xvzf PyYAML-3.09.tar.gz
$ cd PyYAML-3.09
$ sudo python32 setup.py install
--
-- test PyYAML installation...
--
$ python32 setup.py test


lxml 2.3

Module lxml depends on libxml2 and libxslt libraries that could be installed from apt repository, but after reading what are the recommended versions of libraries in lxml documentation, I decided to install the latest versions ob both libraries from source.

$ cd ~/python/lxml
$ wget ftp://xmlsoft.org/libxml2/libxml2-2.7.8.tar.gz
$ wget ftp://xmlsoft.org/libxml2/libxslt-1.1.26.tar.gz
$ wget http://pypi.python.org/packages/source/l/lxml/lxml-2.3.tar.gz


$ tar xvzf libxml2-2.7.8.tar.gz
$ cd libxml2-2.7.8
$ ./configure
$ make
$ sudo make install


$ cd ..
$ tar xvzf libxslt-1.1.26.tar.gz
$ cd libxslt-1.1.26
$ ./configure
$ make
$ sudo make install

Finally, we can install lxml:

$ tar xvzf lxml-2.3.tar.gz
$ cd lxml-2.3
$ python32 setup.py build
$ sudo python32 setup.py install

After installation run a test by printing versions of lxml, libxml2 and libxslt:

$ python32
>> from lxml import etree
>> print(etree.LXML_VERSION)
>> print(etree.LIBXML_VERSION)
>> print(etree.LIBXSLT_VERSION)

PyQt 4.8.3

I followed instructions that you can find at:
http://www.riverbankcomputing.co.uk/static/Docs/PyQt4/html/installation.html

Note:
After my first failed attempt to compile PyQt, I realized that I need to install libxext-dev to avoid error:

...
...
/usr/bin/ld: cannot find -lXext
collect2: ld returned 1 exit status
make[1]: *** [QtHelp.so] Error 1
make[1]: Leaving directory `/home/alesk/python/PyQt/PyQt-x11-gpl-4.8.3/QtHelp'
make: *** [all] Error 2
...

You can install the package with:

$ sudo apt-get install libxext-dev

Note: sip module is a prerequisite before we can configure & build PyQt!

$ cd PyQt
$ wget http://www.riverbankcomputing.com/static/Downloads/sip4/sip-4.12.1.tar.gz
$ cd sip-4.12.1
$ python32 configure.py
$ make
$ sudo make install
$ cd ..

Now, we can download, build and install PyQt:

$ wget http://www.riverbankcomputing.com/static/Downloads/PyQt4/PyQt-x11-gpl-4.8.3.tar.gz
$ tar xvzf PyQt-x11-gpl-4.8.3.tar.gz
$ cd PyQt-x11-gpl-4.8.3
$ python32 configure.py

Do you accept the terms of the license? yes

$ make
$ sudo make install

Make s simple test of PyQt installation…

$ python32
>> from PyQt4.QtCore import QT_VERSION_STR
>> print(QT_VERSION_STR)