Python gestion et déploiement de modules externes¶
Il existe un projet qui permet de gérer plus facilement les modules externes
Comme beaucoup de projet l’arrivée de Python3 a déclaré la fin de certains projets et la création de nouveau.
Installation d’un module externe¶
Python < 2.8¶
La solution la plus simple est d’utiliser easy_install
Pour l’installer il suffit d’aller sur https://pypi.python.org/pypi/setuptools puis de télécharger et de lancer l’executable
cela génère dans le dossier scripts de python un excecutable nommé easy_install
Pour l’utiliser rien de plus simple
easy_install jinja2
Python > 3.0¶
La il faut changer d’outil pour utiliser pip
Aller sur http://www.pip-installer.org/en/latest/installing.html et suivre les instructions en lançant get-pip.py
Sinon on peut le faire manuellement, il faut tout d’abord télécharger et installer distribute sur https://pypi.python.org/pypi/distribute (version 0.6.49)
Puis pour lancer l’installation
python setup.py install
faire la même chose avec pip sur https://pypi.python.org/pypi/pip/1.2.1
python setup.py install
cela génère dans le dossier scripts de python un excecutable nommé pip
pour l’utilisation rien de plus simple
pip install simplejson
pip install --upgrade simplejson
pip uninstall simplejson
Il est possible d’utiliser pip à travers un proxy
pip install --proxy=myboite\mylogin:mypassword@proxy.myboite.fr:8080 ablog
Création d’un module externe¶
Il existe plusieurs moyens pour fournir à d’autres des outils développés en python. Suivant ce qui a été produit (application ou module) on peut imaginer leurs déploiement par:
- un installateur (un msi ou exe pour windows, un deb ou rpm pour linux, ...)
- un egg: un fichier zip directement utilisable par python
- l’utilisation de pip ou setuptools
Nous allons voir comment comment utiliser setuptools (ed donc pip) pour réaliser tout cela.
Nous allons imaginer de créer le module mytools ayant la structure suivante
mytools
|_ mytools
| |_ __init__.py
| |_ parser.py
| |_ sample
| |_ sample1.py
|_ setup.py
Le fichier __init__.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Module mytools.
Tout les outils idispensables pour python
"""
__version__ = "0.0.1"
from parser import OptionParser
Note
l’import d’OptionParser dans le init permet de faire “from mytools import OptionParser” au lieu de “from mytools.parser import OptionParser”. cela est donc plus simple pour importer des classes importantes du module
Le fichier parser.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Implémentation de parser avec de la couleur
"""
import colorconsole, colorconsole.terminal
import os, sys
import optparse
__all__ = ['OptionParser']
import colorconsole, colorconsole.terminal
import os, sys
import optparse
class OptionParser(optparse.OptionParser):
def __init__(self, screen=None, **kw):
optparse.OptionParser.__init__(self, **kw)
if screen == None:
screen = colorconsole.terminal.get_terminal()
self.screen = screen
def exit(self, status=0, msg=None):
if msg:
sys.stderr.write(msg)
self.screen.set_color(colorconsole.terminal.colors["WHITE"], colorconsole.terminal.colors["BLACK"])
sys.exit(status)
def error(self, msg):
self.screen.set_color(colorconsole.terminal.colors["LRED"], None)
optparse.OptionParser.error(self, msg)
def print_version(self, file=None):
self.screen.set_color(colorconsole.terminal.colors["LGREEN"],None)
optparse.OptionParser.print_version(self, file)
self.screen.set_color(colorconsole.terminal.colors["WHITE"], colorconsole.terminal.colors["BLACK"])
def print_help(self, file=None):
self.screen.set_color(colorconsole.terminal.colors["LGREEN"],None)
optparse.OptionParser.print_help(self, file)
self.screen.set_color(colorconsole.terminal.colors["WHITE"], colorconsole.terminal.colors["BLACK"])
def print_info(self, msg=""):
self.screen.set_color(colorconsole.terminal.colors["LGREEN"],None)
print(msg)
self.screen.set_color(colorconsole.terminal.colors["WHITE"], colorconsole.terminal.colors["BLACK"])
def print_stdout(self, msg, fg="WHITE", bg="BLACK"):
self.screen.set_color(colorconsole.terminal.colors[fg],colorconsole.terminal.colors[bg])
sys.stdout.write(msg)
self.screen.set_color(colorconsole.terminal.colors["WHITE"], colorconsole.terminal.colors["BLACK"])
def get_formatwidth(self, default=80):
try:
width = int(os.environ['COLUMNS'])
except (KeyError, ValueError):
width = default
return "%-"+str(width)+"s"
Note
Il est important de documenter son module. l’utilisation de __all__ permet de n’autoriser que certains éléments a être importable ... afin de faciliter la gestion du module pour les utilisateurs
Le fichier sample1.py
import sys, traceback
from mytools.parser import OptionParser
import os
VERSION="0.1"
PROG="sample1"
DESCRIPTION="""description of sample1"""
AUTHOR="Frederic Aoustin"
if __name__ == '__main__':
usage = "usage: %prog [options]"
parser = OptionParser(version="%s %s" % (PROG,VERSION), usage=usage)
parser.description= DESCRIPTION
parser.epilog = AUTHOR
parser.add_option("-a","--arg",
dest = "myarg",
action = "store_true",
help = "arg by default False",
default = False)
try:
(options, args) = parser.parse_args()
if options.myarg:
parser.error("myarg is True, error ;-)")
sys.exit()
except Exception as e:
parser.error(e)
sys.exit(1)
On peut maintenant tester notre module mytools
C:\Users\fraoustin\Google Drive\project\mytools>set PYTHONPATH=%PYTHONPATH%;.
C:\Users\fraoustin\Google Drive\project\mytools>python mytools\sample\sample1.py -h
Usage: sample1.py [options]
description of sample1
Options:
--version show program's version number and exit
-h, --help show this help message and exit
-a, --arg arg by default False
Frederic Aoustin
Note
on remarque que nous modifions notre PYTHONPATH afin de pouvoir charger notre module Notre installateur nous permettra d’éviter cette action
Le fichier setup.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from setuptools import setup, find_packages
import mytools
setup(
name='mytools',
version=mytools.__version__,
packages=find_packages(),
author="Frederic Aoustin",
author_email="fraoustin@gmail.com",
description="mes outils pour python",
long_description="mes super outils pour python",
install_requires= ['colorconsole'], #on peut preciser une version "colorconsole >= 0.1"
include_package_data=False, #mettre True si vous avez un fichier manifest.ini
url='http://mypage.com',
# liste des marqueurs disponible sur:https://pypi.python.org/pypi?%3Aaction=list_classifiers
classifiers=[
"Programming Language :: Python",
"Development Status :: 3 - Alpha",
"License :: OSI Approved",
"Natural Language :: French",
"Operating System :: OS Independent",
"Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.0",
"Programming Language :: Python :: 3.1",
"Programming Language :: Python :: 3.2",
"Programming Language :: Python :: 3.3",
"Programming Language :: Python :: 3.4",
"Topic :: Communications",
"Topic :: Terminals",
],
# La syntaxe est "nom-de-commande-a-creer = package.module:fonction".
#entry_points = {
# 'console_scripts': [
# 'proclame-sm = sm_lib.core:proclamer',
# ],
#},
)
Nous n’utilisons pas de fichier manifest.ini mais il peut être utile si on ne souhaite pas par exemple exclure le répertoire sample mais inclure des fichiers jpg par exemple
exclude sample
include *.jpg
La notion de entry_point permet d’obtenir des scripts qui lance automatiquement la fonction identifiée.
Maintenant on peut:
- installer notre module
python setup.py install
- créer une source de distribution
python setup.py sdist --formats=tar,zip
- créer un module eegs
python setup.py bdist_egg
- créer un installateur windows
python setup.py bdist_wininst
Pour ajouter notre module sur le site pypi
créer un nouveau compte si besoin (option 2)
python setup.py register
ce connecter à son compte (option 1)
python setup.py register
cela permet de créer un fichier .pypirc au niveau de votre home contenant
[distutils]
index-servers =
pypi
[pypi]
username:fraoustin
password:V=4/3pir3
puis par la suite créer une source de distribution et la mettre en ligne
python setup.py sdist upload
Note
si vous avez une erreur 401 d’authentification il faut mettre à jours le module distribute via un “pip install –upgrade distribute”
vous pouvez maintenant l’installer depuis pypi
pip install mytools
La comparaison de version pour l’outil est réalisée ainsi
>>> from distutils.version import StrictVersion
>>> StrictVersion('10.4.10') > StrictVersion('10.4.9')
True