Tutoriel n° 7 - Démarrer cette (troisième) partie

Jusqu’à présent, l’application que nous avons construite n’a utilisé que notre propre code, ainsi que le code fourni par BeeWare. Cependant, dans une application réelle, vous voudrez probablement utiliser une bibliothèque tierce, téléchargée à partir du Python Package Index (PyPI).

Modifions notre application pour y inclure une bibliothèque tierce.

Accéder à une API

Une tâche courante qu’une application doit effectuer est de faire une requête sur une API web pour récupérer des données, et afficher ces données à l’utilisateur. Comme il s’agit d’une application jouet, nous n’avons pas de vraie API à utiliser. Nous utiliserons donc la {JSON} Placeholder API comme source de données.

L’API {JSON} Placeholder possède un certain nombre de « faux » points de terminaison d’API que vous pouvez utiliser comme données de test. L’une de ces API est le point de terminaison /posts/, qui renvoie de faux billets de blog. Si vous ouvrez https://jsonplaceholder.typicode.com/posts/42 dans votre navigateur, vous obtiendrez un fichier JSON décrivant un seul article - un contenu Lorum ipsum pour un article de blog avec l’ID 42.

La bibliothèque standard de Python contient tous les outils dont vous avez besoin pour accéder à une API. Cependant, les API intégrées sont de très bas niveau. Ce sont de bonnes implémentations du protocole HTTP, mais elles exigent de l’utilisateur qu’il gère de nombreux détails de bas niveau, comme la redirection d’URL, les sessions, l’authentification et l’encodage des données utiles. En tant qu“« utilisateur normal de navigateur », vous avez probablement l’habitude de considérer ces détails comme allant de soi, car le navigateur les gère pour vous.

En conséquence, des bibliothèques tierces ont été développées pour envelopper les API intégrées et fournir une API plus simple qui correspond mieux à l’expérience quotidienne du navigateur. Nous allons utiliser l’une de ces bibliothèques pour accéder à l’API {JSON} Placeholder - une bibliothèque appelée httpx.

Ajoutons un appel API httpx à notre application. Ajoutez un import au début de app.py pour importer httpx: :

import httpx

Ensuite, modifiez le callback say_hello() pour qu’il ressemble à ceci: :

def say_hello(self, widget):
    with httpx.Client() as client:
        response = client.get("https://jsonplaceholder.typicode.com/posts/42")

    payload = response.json()

    self.main_window.info_dialog(
        greeting(self.name_input.value),
        payload["body"],
    )

Cela modifiera le callback say_hello() de telle sorte que lorsqu’il est invoqué, il le fera :

  • effectuer une requête GET sur l’API JSON pour obtenir le poste 42 ;

  • décoder la réponse en JSON ;

  • extraire le corps du message ; et

  • inclure le corps de ce message dans le texte du dialogue.

Exécutons notre application mise à jour dans le mode développeur de Briefcase pour vérifier que notre changement a fonctionné.

(beeware-venv) $ briefcase dev
Traceback (most recent call last):
File ".../venv/bin/briefcase", line 5, in <module>
    from briefcase.__main__ import main
File ".../venv/lib/python3.9/site-packages/briefcase/__main__.py", line 3, in <module>
    from .cmdline import parse_cmdline
File ".../venv/lib/python3.9/site-packages/briefcase/cmdline.py", line 6, in <module>
    from briefcase.commands import DevCommand, NewCommand, UpgradeCommand
File ".../venv/lib/python3.9/site-packages/briefcase/commands/__init__.py", line 1, in <module>
    from .build import BuildCommand  # noqa
File ".../venv/lib/python3.9/site-packages/briefcase/commands/build.py", line 5, in <module>
    from .base import BaseCommand, full_options
File ".../venv/lib/python3.9/site-packages/briefcase/commands/base.py", line 14, in <module>
    import httpx
ModuleNotFoundError: No module named 'httpx'

Qu’est-ce qui s’est passé ? Nous avons ajouté httpx à notre code, mais nous ne l’avons pas ajouté à notre environnement virtuel de développement. Nous pouvons corriger cela en installant httpx avec pip, puis en relançant briefcase dev :

(beeware-venv) $ python -m pip install httpx
(beeware-venv) $ briefcase dev

Lorsque vous entrez un nom et que vous appuyez sur le bouton, une boîte de dialogue doit s’afficher :

Tutoriel Hello World 7 dialogue, sur macOS

Nous avons maintenant une application fonctionnelle, utilisant une bibliothèque tierce, fonctionnant en mode développement !

Exécution de l’application mise à jour

Nous allons faire en sorte que ce code d’application mis à jour soit empaqueté en tant qu’application autonome. Puisque nous avons modifié le code, nous devons suivre les mêmes étapes que dans Tutoriel 4 :

Mettre à jour le code dans l’application packagée :

(beeware-venv) $ briefcase update

[helloworld] Updating application code...
...

[helloworld] Application updated.

Reconstruire l’application :

(beeware-venv) $ briefcase build

[helloworld] Adhoc signing app...
[helloworld] Built build/helloworld/macos/app/Hello World.app

Enfin, lancez l’application :

(beeware-venv) $ briefcase run

[helloworld] Starting app...
===========================================================================

Cependant, lorsque l’application s’exécute, vous verrez une erreur dans la console, ainsi qu’une boîte de dialogue de plantage :

Plantage de l'application Hello World Tutorial 7, sur macOS

Une fois de plus, l’application n’a pas pu démarrer parce que httpx a été installé - mais pourquoi ? N’avons-nous pas déjà installé httpx ?

Nous l’avons fait, mais uniquement dans l’environnement de développement. Votre environnement de développement est entièrement local à votre machine - et n’est activé que lorsque vous l’activez explicitement. Bien que Briefcase dispose d’un mode de développement, la principale raison pour laquelle vous utilisez Briefcase est d’empaqueter votre code afin de le donner à quelqu’un d’autre.

La seule façon de garantir que quelqu’un d’autre disposera d’un environnement Python contenant tout ce dont il a besoin est de construire un environnement Python complètement isolé. Cela signifie qu’il y a une installation Python complètement isolée, et un ensemble de dépendances complètement isolé. C’est ce que Briefcase construit quand vous lancez briefcase build - un environnement Python isolé. Cela explique aussi pourquoi httpx n’est pas installé - il a été installé dans votre environnement de développement, mais pas dans l’application packagée.

Nous devons donc indiquer à Briefcase que notre application a une dépendance externe.

Mise à jour des dépendances

Dans le répertoire racine de votre application, il y a un fichier nommé pyproject.toml. Ce fichier contient tous les détails de configuration de l’application que vous avez fournis lorsque vous avez lancé briefcase new.

pyproject.toml est divisé en sections ; l’une d’entre elles décrit les paramètres de votre application: :

[tool.briefcase.app.helloworld]
formal_name = "Hello World"
description = "A Tutorial app"
long_description = """More details about the app should go here.
"""
sources = ["src/helloworld"]
requires = []

L’option requires décrit les dépendances de notre application. C’est une liste de chaînes de caractères, spécifiant les bibliothèques (et, optionnellement, les versions) des bibliothèques que vous voulez inclure dans votre application.

Modifiez le paramètre requires de façon à ce qu’il se lise: :

requires = [
    "httpx",
]

En ajoutant ce paramètre, nous disons à Briefcase « lorsque vous compilez mon application, lancez pip install httpx dans le bundle de l’application ». Tout ce qui serait une entrée légale pour pip install` peut être utilisé ici - ainsi, vous pourriez spécifier :

  • Une version spécifique de la bibliothèque (par exemple, "httpx==0.19.0") ;

  • Une gamme de versions de la bibliothèque (par exemple, "httpx>=0.19") ;

  • Un chemin vers un dépôt git (par exemple, "git+https://github.com/encode/httpx") ; ou

  • Un chemin d’accès à un fichier local (Cependant, attention : si vous donnez votre code à quelqu’un d’autre, ce chemin d’accès n’existera probablement pas sur sa machine !)

Plus loin dans pyproject.toml, vous remarquerez d’autres sections qui dépendent du système d’exploitation, comme [tool.briefcase.app.helloworld.macOS] et [tool.briefcase.app.helloworld.windows]. Ces sections ont également un paramètre requires. Ces paramètres vous permettent de définir des dépendances supplémentaires spécifiques à une plate-forme - ainsi, par exemple, si vous avez besoin d’une bibliothèque spécifique à une plate-forme pour gérer un aspect de votre application, vous pouvez spécifier cette bibliothèque dans la section requires'' spécifique à la plate-forme, et ce paramètre ne sera utilisé que pour cette plate-forme. Vous remarquerez que les bibliothèques ``toga sont toutes spécifiées dans la section requires spécifique à la plate-forme - c’est parce que les bibliothèques nécessaires pour afficher une interface utilisateur sont spécifiques à la plate-forme.

Dans notre cas, nous voulons que httpx soit installé sur toutes les plateformes, donc nous utilisons le paramètre requires au niveau de l’application. Les dépendances au niveau de l’application seront toujours installées ; les dépendances spécifiques à la plate-forme sont installées en plus de celles au niveau de l’application.

Certains paquets binaires peuvent ne pas être disponibles

Sur les plateformes de bureau (macOS, Windows, Linux), tout pip-installable peut être ajouté à vos exigences. Sur les plateformes mobiles et web, vos options sont légèrement limitées.

En bref, tout paquetage pure Python (c’est-à-dire les paquetages qui ne contiennent pas de module binaire) peut être utilisé sans difficulté. Cependant, si votre dépendance contient un composant binaire, il doit être compilé ; à l’heure actuelle, la plupart des paquets Python ne fournissent pas de support de compilation pour les plates-formes autres que les ordinateurs de bureau.

BeeWare peut fournir des binaires pour certains modules binaires populaires (y compris numpy, pandas, et cryptographie). Il est habituellement possible de compiler des paquets pour les plateformes mobiles, mais ce n’est pas facile à mettre en place – ce qui sort du cadre d’un tutoriel d’introduction comme celui-ci.

Maintenant que nous avons informé Briefcase de nos exigences supplémentaires, nous pouvons essayer d’empaqueter à nouveau notre application. Assurez-vous que vous avez sauvegardé vos changements dans pyproject.toml, puis mettez à jour votre application à nouveau - cette fois-ci, en passant le drapeau -r. Cela indique à Briefcase de mettre à jour les exigences dans l’application packagée :

(beeware-venv) $ briefcase update -r

[helloworld] Updating application code...
Installing src/hello_world...

[helloworld] Updating requirements...
Collecting httpx
  Using cached httpx-0.27.0-py3-none-any.whl.metadata (7.2 kB)
...
Installing collected packages: zipp, typing-extensions, travertino, sniffio, pycairo, idna, h11, exceptiongroup, certifi, pygobject, importlib-metadata, httpcore, anyio, toga-core, httpx, gbulb, toga-gtk
Successfully installed anyio-4.3.0 certifi-2024.2.2 exceptiongroup-1.2.1 gbulb-0.6.5 h11-0.14.0 httpcore-1.0.5 httpx-0.27.0 idna-3.7 importlib-metadata-7.1.0 pycairo-1.26.0 pygobject-3.48.2 sniffio-1.3.1 toga-core-0.4.4 toga-gtk-0.4.4 travertino-0.3.0 typing-extensions-4.11.0 zipp-3.18.1

[helloworld] Removing unneeded app content...
...

[helloworld] Application updated.

Une fois la mise à jour effectuée, vous pouvez lancer briefcase build et briefcase run - et vous devriez voir votre application packagée, avec le nouveau comportement du dialogue.

Note

L’option -r pour la mise à jour des exigences est également honorée par les commandes build et run, donc si vous voulez mettre à jour, compiler et exécuter en une seule étape, vous pouvez utiliser briefcase run -u -r.

Étapes suivantes

Nous avons maintenant une application qui utilise une bibliothèque tierce ! Cependant, vous avez peut-être remarqué que lorsque vous appuyez sur le bouton, l’application ne répond plus vraiment. Pouvons-nous faire quelque chose pour résoudre ce problème ? Consultez Tutoriel 8 pour le savoir…