Tutoriel avancé : concevoir des applications réutilisables

Ce tutoriel avancé commence là où le tutoriel 7 s’est arrêté. Nous allons transformer notre application de sondage Web en un paquet Python autonome qu’il sera possible de réutiliser dans de nouveaux projets et de partager avec d’autres personnes.

Si vous n’avez pas récemment suivi les tutoriels 1–7, nous vous encourageons à les parcourir à nouveau afin que votre exemple de projet corresponde à celui qui est décrit ci-dessous.

Importance du recyclage

C’est un gros travail de concevoir, construire, tester et maintenir une application Web. Beaucoup de projets Python et Django ont des problématiques communes. Ne serait-il pas merveilleux si nous pouvions économiser un peu de ce travail répétitif ?

Reusability is the way of life in Python. The Python Package Index (PyPI) has a vast range of packages you can use in your own Python programs. Check out Django Packages for existing reusable apps you could incorporate in your project. Django itself is also just a Python package. This means that you can take existing Python packages or Django apps and compose them into your own web project. You only need to write the parts that make your project unique.

Disons que vous débutez un nouveau projet qui nécessite une application de sondage telle que celle sur laquelle nous avons travaillé. Comme pouvez-vous recycler cette application ? Heureusement, vous êtes déjà sur la bonne voie. Dans le tutoriel 3, nous avons vu comment découpler les sondages de l’URLconf de base du projet en utilisant un include. Dans ce tutoriel, nous irons un peu plus loin pour rendre l’application simple à utiliser dans de nouveaux projets et prête à être publiée pour que d’autres puissent l’installer et l’exploiter.

Paquet ? Application ?

Un paquet Python permet de regrouper du code Python pour qu’il puisse être facilement réutilisé. Un paquet contient un ou plusieurs fichiers de code Python (aussi connus sous le nom de « modules »).

Un paquet peut être importé avec import foo.bar ou from foo import bar. Pour qu’un répertoire (comme polls) constitue un paquet, il doit contenir un fichier spécial __init__.py, même si ce dernier est vide.

Une application Django n’est qu’un paquet Python qui est spécialement prévu pour fonctionner dans un projet Django. Une application peut utiliser des conventions Django partagées, comme la présence de sous-modules models, tests, urls et views.

Par la suite, nous utilisons le terme empaquetage (packaging) pour décrire le processus de création d’un paquet Python facile à installer par tout le monde. Cela peut prêter à confusion, effectivement.

Votre projet et votre application recyclable

Après les tutoriels précédents, notre projet devrait ressembler à ceci :

mysite/
    manage.py
    mysite/
        __init__.py
        settings.py
        urls.py
        wsgi.py
    polls/
        __init__.py
        admin.py
        migrations/
            __init__.py
            0001_initial.py
        models.py
        static/
            polls/
                images/
                    background.gif
                style.css
        templates/
            polls/
                detail.html
                index.html
                results.html
        tests.py
        urls.py
        views.py
    templates/
        admin/
            base_site.html

Vous avez créé mysite/templates dans le tutoriel 7 et polls/templates dans le tutoriel 3. Il est peut-être maintenant plus facile de comprendre pourquoi nous avons séparé les répertoires de gabarits du projet de ceux de l’application : tout ce qui fait partie de l’application de sondage se trouve dans polls. L’application forme un tout par elle-même et est ainsi plus facile à intégrer dans un nouveau projet.

Le répertoire polls pourrait maintenant être copié dans un nouveau projet Django pour être immédiatement utilisé. L’application n’est cependant pas encore tout à fait prête pour être publiée. Pour cela, il faut encore empaqueter l’application afin que d’autres puissent facilement l’installer.

Installation de quelques prérequis

L’état actuel de la construction de paquets Python est un peu embrouillé par l’utilisation de plusieurs outils. Dans ce tutoriel, nous allons utiliser setuptools pour construire nos paquets. C’est l’outil d’empaquetage que nous recommandons (fusionné avec le dérivé distribute). Nous utiliserons aussi pip pour l’installer et le désinstaller. Vous devriez installer maintenant ces deux paquets. Si vous avez besoin d’aide, vous pouvez vous référer à comment installer Django avec pip. Vous pouvez installer setuptools de la même manière.

Empaquetage de l’application

L’empaquetage Python se réfère à la préparation d’une application dans un format spécifique qui peut être facilement installé et utilisé. Django lui-même est empaqueté de manière très semblable. Pour une petite application comme la nôtre, ce processus n’est pas trop difficile.

  1. Premièrement, créez un répertoire parent pour polls, en dehors de votre projet Django. Nommez ce répertoire django-polls.

    Choix d’un nom pour votre application

    Au moment de choisir un nom pour votre paquet, consultez les ressources comme PyPI pour éviter des conflits de nom avec des paquets existants. Il est souvent utile de préfixer votre nom de module avec django- lors de la création d’un paquet à distribuer. Les personnes qui cherchent des applications Django peuvent ainsi identifier plus facilement votre application comme étant spécifique à Django.

    Les étiquettes d’applications (c’est-à-dire la partie finale du chemin pointé vers le paquet de l’application) figurant dans INSTALLED_APPS doivent être uniques. Évitez d’utiliser la même étiquette que l’une des applications contribuées de Django, par exemple auth, admin ou messages.

  2. Déplacez le répertoire polls dans le répertoire django-polls.

  3. Créez un fichier django-polls/README.rst contenant ceci :

    django-polls/README.rst
    =====
    Polls
    =====
    
    Polls is a simple Django app to conduct Web-based polls. For each
    question, visitors can choose between a fixed number of answers.
    
    Detailed documentation is in the "docs" directory.
    
    Quick start
    -----------
    
    1. Add "polls" to your INSTALLED_APPS setting like this::
    
        INSTALLED_APPS = [
            ...
            'polls',
        ]
    
    2. Include the polls URLconf in your project urls.py like this::
    
        url(r'^polls/', include('polls.urls')),
    
    3. Run `python manage.py migrate` to create the polls models.
    
    4. Start the development server and visit http://127.0.0.1:8000/admin/
       to create a poll (you'll need the Admin app enabled).
    
    5. Visit http://127.0.0.1:8000/polls/ to participate in the poll.
    
  4. Créez un fichier django-polls/LICENSE. Le choix d’une licence n’est pas dans le thème de ce tutoriel, mais nous vous rendons attentif au fait que du code publié sans licence est inutile. Django et de nombreuses applications compatibles Django sont distribués sous licence BSD ; vous êtes bien sûr libre d’utiliser la licence de votre choix. Sachez seulement que le choix de la licence a un impact sur la quantité d’utilisateurs potentiels de votre code.

  5. Ensuite, nous allons créer un fichier setup.py qui fournit des détails sur la façon de construire et d’installer l’application. Nous ne nous lancerons pas dans une explication détaillée de ce fichier, mais vous trouverez plus d’informations dans la documentation de setuptools. Créez un fichier django-polls/setup.py avec le contenu suivant :

    django-polls/setup.py
    import os
    from setuptools import find_packages, setup
    
    with open(os.path.join(os.path.dirname(__file__), 'README.rst')) as readme:
        README = readme.read()
    
    # allow setup.py to be run from any path
    os.chdir(os.path.normpath(os.path.join(os.path.abspath(__file__), os.pardir)))
    
    setup(
        name='django-polls',
        version='0.1',
        packages=find_packages(),
        include_package_data=True,
        license='BSD License',  # example license
        description='A simple Django app to conduct Web-based polls.',
        long_description=README,
        url='https://www.example.com/',
        author='Your Name',
        author_email='yourname@example.com',
        classifiers=[
            'Environment :: Web Environment',
            'Framework :: Django',
            'Framework :: Django :: X.Y',  # replace "X.Y" as appropriate
            'Intended Audience :: Developers',
            'License :: OSI Approved :: BSD License',  # example license
            'Operating System :: OS Independent',
            'Programming Language :: Python',
            # Replace these appropriately if you are stuck on Python 2.
            'Programming Language :: Python :: 3',
            'Programming Language :: Python :: 3.4',
            'Programming Language :: Python :: 3.5',
            'Topic :: Internet :: WWW/HTTP',
            'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
        ],
    )
    
  6. Seuls des modules et paquets Python sont inclus par défaut dans le paquet. Pour ajouter des fichiers supplémentaires, nous devrons créer un fichier MANIFEST.in. La documentation de setuptools mentionnée à l’étape précédente présente ce fichier en détails. Pour inclure les gabarits et les fichiers README.rst et LICENSE, créez un fichier django-polls/MANIFEST.in avec le contenu suivant :

    django-polls/MANIFEST.in
    include LICENSE
    include README.rst
    recursive-include polls/static *
    recursive-include polls/templates *
    
  7. Il est facultatif, mais recommandé, d’inclure de la documentation détaillée dans votre application. Créez un répertoire vide django-polls/docs en prévision de contenu documentaire. Ajoutez une ligne supplémentaire dans django-polls/MANIFEST.in:

    recursive-include docs *
    

    Notez que le répertoire docs ne sera pas inclus dans votre paquet tant que vous n’y ajoutez pas de fichier. Beaucoup d’applications Django offrent aussi un version en ligne de leur documentation par le moyen de sites comme readthedocs.org.

  8. Essayez de construire votre paquet avec python setup.py sdist (lancé depuis django-polls). Cela va créer un répertoire nommé dist et construire votre nouveau paquet, django-polls-0.1.tar.gz.

For more information on packaging, see Python’s Tutorial on Packaging and Distributing Projects.

Utilisation de son propre paquet

Comme nous avons déplacé le répertoire polls hors du projet, celui-ci ne fonctionne plus. Nous allons maintenant corriger ça en installant notre nouveau paquet django-polls.

Installation en tant que bibliothèque utilisateur

Les étapes suivantes installent django-polls comme une bibliothèque utilisateur. Les installations « utilisateur » comportent bien des avantages sur l’installation de paquets au niveau système, comme de pouvoir être utilisables sur des systèmes dont vous n’êtes pas administrateur ou pour éviter que le paquet ne perturbe des services du système ou d’autres utilisateurs de la machine.

Notez que les installations « utilisateur » peuvent tout de même influencer le comportement d’outils système qui tournent sous l’identité de cet utilisateur, il est donc plus robuste d’utiliser virtualenv (voir ci-dessous).

  1. Pour installer le paquet, utilisez pip (vous l’avez déjà installé, n’est-ce pas ?) :

    pip install --user django-polls/dist/django-polls-0.1.tar.gz
    
  2. Si tout va bien, votre projet Django devrait de nouveau fonctionner correctement. Lancez à nouveau le serveur pour le vérifier.

  3. Pour désinstaller le paquet, utilisez pip :

    pip uninstall django-polls
    

Publication de l’application

Après avoir empaqueté et testé django-polls, il est prêt à être partagé avec le monde entier ! Si ce n’était pas qu’un exemple, vous pourriez maintenant :

Installation de paquets Python avec virtualenv

Précédemment, nous avons installé l’application de sondage comme bibliothèque utilisateur. Cela comporte quelques désavantages :

  • La modification de bibliothèques utilisateurs peut influencer d’autres logiciels Python sur votre système.

  • Vous ne pourrez pas faire fonctionner plusieurs versions de ce paquet en parallèle (ou avec d’autres portant le même nom).

Typiquement, ces situations ne se produisent que lorsque vous maintenez plusieurs projets Django. Dans ces cas, la meilleure solution est d’utiliser virtualenv. Cet outil permet de maintenir plusieurs environnements Python isolés les uns des autres, ayant chacun leur propre copie des bibliothèques et de l’espace de nom des paquets.

Back to Top