Construire un chatbot avec le moteur GPT-3 d'OpenAI, Twilio SMS et Python

August 03, 2020
Rédigé par
Révisé par
Matt Makai
Twilion
Diane Phan
Twilion

Construire un chatbot avec le moteur GPT-3 d'OpenAI, Twilio SMS et Python

Un chatbot GPT-3 est une application logicielle capable de mener une conversation avec un utilisateur humain par le biais d'un langage écrit ou parlé. Le niveau d'« intelligence » entre les chatbots varie considérablement. Bien que certains chatbots aient une compréhension assez élémentaire du langage, d'autres utilisent des algorithmes sophistiqués d'intelligence artificielle (IA) et de machine learning (ML) pour atteindre un niveau de conversation presque humain.

Dans ce tutoriel, je vais vous montrer à quel point il est facile de construire un chatbot pour Twilio SMS à l'aide de la plate-forme OpenAI et du framework Flask pour Python.

Vous voulez avoir une idée des capacités du GPT-3 ? Regardez l'interaction suivante que j'ai pu avoir avec ce robot à l'aide du projet que nous allons construire dans ce tutoriel :

conversion avec le chatbot openai

Introduction au GPT-3

GPT-3 (Generative Pre-trained Transformer 3) est un modèle de langage très avancé formé sur un très grand corpus de texte. Malgré sa complexité interne, il est étonnamment simple à utiliser : vous lui donnez du texte, et le modèle en génère d'autres, suivant un style et une structure similaires.

Que pensez-vous du premier paragraphe de cet article ? Est-ce que vous me croyez si je vous dis que je ne l'ai pas écrit moi-même, et qu'il a été entièrement généré par GPT-3 ? J'ai nourri le modèle avec le titre et l'introduction de deux autres billets de blog que j'ai écrits dans le passé, et puis j'ai ajouté le titre de cet article. Voici l'entrée complète que j'ai fournie :

Title: Build a WhatsApp Chatbot With Python, Flask and Twilio
Summary: A chatbot is a software application that is able to conduct a conversation with a human
user through written or spoken language. The level of "intelligence" among chatbots varies greatly.
While some chatbots have a fairly basic understanding of language, others employ
sophisticated artificial intelligence (AI) and machine learning (ML) algorithms to achieve an
almost human conversational level. In this tutorial I'm going to show you how easy it is to build a
chatbot for WhatsApp using the Twilio API for WhatsApp and the Flask framework for Python.

Title: Run Your Flask Regularly Scheduled Jobs with Cron
Summary: A common need of web applications is to have a periodically running task in the
background. This could be a task that imports new data from third party sources, or maybe one
that removes revoked tokens from your database once they have expired. In this and many other
situations you are faced with the challenge of implementing a task that runs in the background at
regular intervals. This is a pattern that many people ask me about. I've seen implementations that
are based on the APScheduler package, on Celery, and even homegrown solutions built inside a
background thread. Sadly none of these options are very good. In this article I'm going to show
you what I believe is a very robust implementation that is based on the Flask CLI and the cron
service.

Title: Building an SMS Chatbot with OpenAI's GPT-3 engine, Twilio and Python
Summary:

Notez que les deux premiers blocs de texte ont des lignes de « titre » et de « résumé », mais que la troisième entrée a un résumé vide. Lorsque le moteur GPT-3 examine cette entrée, il comprend qu'il doit remplir la ligne « résumé » avec le texte approprié pour le titre donné. À mon avis, il a plutôt bien réussi !

GPT-3 n'est pas déterministe, dans le sens où, compte tenu de la même entrée, plusieurs exécutions du moteur renvoient des réponses différentes. En fait, j'ai généré quelques paragraphes d'ouverture avec l'entrée ci-dessus et sélectionné celui que j'ai aimé le plus pour commencer l'article. Voici quelques-uns de ces éléments qui méritent d'être présentés :

Summary: I recently read about GPT-3 and was amazed at how advanced this chatbot is. After
reading the article I thought to myself: I want to do that, but I don't have access to a GPU.
Luckily for me, there are some projects that allow you to use a neural network in a non-graphical
environment, and one of these is OpenAI. In this article I'm going to show you how to create a
GPT-3 based chatbot using OpenAI, Twilio and Python.
Summary: In this article I'm going to show you how to create a simple chatbot using the GPT-3
algorithm and the Twilio SMS service. The algorithm will read and respond to text messages and
we'll use the Python wrapper for OpenAI's GPT-3 to do so.

Difficile à croire, non ? Aussi incroyable que cela semble, vous devez être prudent, car le moteur n'a pas une compréhension complète du texte qu'il génère et peut fournir des réponses trompeuses. Regardez ces deux autres paragraphes d'ouverture qu'il a également produits à partir de mes commentaires :

Summary: GPT-3 is a language modeling algorithm developed by Google. It is used to predict the
next word in a sequence of words. This is a common problem in natural language processing and text
generation. In this article I'm going to show you how to build a chatbot that uses GPT-3 to
generate responses to your messages. The chatbot will be able to respond to questions about itself,
the weather, and other topics.
Summary: In this post, I'm going to teach you how to build a super cool GPT-3 powered chatbot using
the OpenAI platform. GPT-3 (Generative Preachers Talk 3) is a neural network that can generate new
sermons for the original Preacher's Talks 3 data set. Using just this data and a few lines of
Python code, we're going to build a chatbot capable of having meaningful conversations about
anything that can be translated into a text message.

Bien que le premier soit vraiment bon en termes de structure, il a une grande erreur factuelle : Google n'a pas développé cette technologie. Quant au deuxième exemple, non seulement il s'est trompé sur l'acronyme GPT-3, mais il est également à la fois ridicule et drôle !

Implémentation d'un chatbot avec GPT-3

Comment pouvons-nous utiliser cette technologie géniale ? En construisant un chatbot, bien sûr !

Nous pouvons « amorcer » le moteur avec un ou deux exemples d'interactions entre l'utilisateur et l'IA pour définir le ton du bot. Nous ajoutons ensuite l'invite réelle de l'utilisateur à la fin et laissons le moteur générer la réponse.

Voici un exemple de requête initiale qui fonctionne pour un chatbot :

Human: Hello, who are you?
AI: I am doing great. How can I help you today?
Human: Who played Forrest Gump in the movie?
AI:

L'échange dans les deux premières lignes est inventé. Il sert à faire savoir au GPT-3 que nous voulons des lignes alternées qui commencent par « Human : » (Humain) et « AI : » (IA) et que l'IA va répondre aux questions. La troisième ligne est la première question réelle de l'utilisateur.

Lorsque j'ai transmis cette entrée au moteur, j'ai reçu le texte suivant :

AI: Tom Hanks.

Jusque là, tout va bien. Disons maintenant que l'utilisateur veut poser une autre question. Ici, nous avons la possibilité d'intégrer cette dernière interaction dans l'entrée, car cela aidera le GPT-3 à avoir un meilleur contexte de conversation. Voici ce qui pourrait être entré pour une question de suivi :

Human: Hello, who are you?
AI: I am doing great. How can I help you today?
Human: Who played Forrest Gump in the movie?
AI: Tom Hanks.
Human: Was he in any other great roles?
AI:

Vous pouvez probablement comprendre pourquoi il était judicieux d'élargir l'entrée avec la question et la réponse précédentes. L'utilisateur pose maintenant une question sur « he » (lui), en partant du principe que le chatbot se souviendra que la question précédente portait sur Tom Hanks.

Heureusement, le GPT-3 relève le défi. Voici la réponse :

AI: Yes, he was the star of Big, Saving Private Ryan, and You've Got Mail.

Prêt à construire un chatbot basé sur cet algorithme simple ? Allons-y.

Prérequis pour ce tutoriel

Pour suivre ce tutoriel, vous avez besoin des éléments suivants :

Création d'un environnement virtuel Python

Selon les meilleures pratiques Python, la première étape de la création du chatbot consiste à créer un répertoire distinct pour le projet en vue d'y créer un environnement virtuel. Nous allons ensuite installer les packages Python dont nous avons besoin pour notre chatbot.

Si vous utilisez un système Unix ou Mac OS, ouvrez un terminal et entrez les commandes suivantes pour effectuer les tâches décrites ci-dessus :

$ mkdir twilio-openai-bot
$ cd twilio-openai-bot
$ python3 -m venv venv
$ source venv/bin/activate
(venv) $ pip install openai twilio flask python-dotenv pyngrok

Pour ceux qui suivent le didacticiel sous Windows, entrez les commandes suivantes dans une fenêtre d'invite de commande :

$ md twilio-openai-bot
$ cd twilio-openai-bot
$ python -m venv venv
$ venv\Scripts\activate
(venv) $ pip install openai twilio flask python-dotenv pyngrok

La dernière commande utilise pip, le programme d'installation du package, pour installer les trois packages Python que nous allons utiliser dans ce projet, qui sont :

Configuration

Comme mentionné ci-dessus, ce projet nécessite une clé API d'OpenAI. Au moment où je rédige ce texte, la seule façon d'en obtenir une est d'être accepté dans leur programme bêta privé. Vous pouvez faire une demande sur leur site.

L'application Python devra avoir accès à cette clé. Nous allons donc créer un fichier .env dans lequel l'insérer. L'application l'importe ensuite à partir de ce fichier en tant que variable d'environnement.

Créez un fichier .env dans votre répertoire de projet (faites attention au point de début) et entrez une seule ligne de texte contenant les éléments suivants :

OPENAI_KEY=your-openai-api-key-here

Vous apprendrez comment utiliser ce fichier dans la section suivante. Si vous prévoyez de versionner votre code source, assurez-vous que ce fichier est exclu, car vous ne voulez pas partager accidentellement votre clé OpenAI.

Envoi de requêtes GPT-3 depuis Python

Dans cette section, nous allons créer le code de support qui nous permettra de travailler avec le moteur GPT-3 d'OpenAI. Le code sera stocké dans un fichier appelé chatbot.py. Vous trouverez ci-dessous la section d'initialisation de ce fichier :

import os
from dotenv import load_dotenv
import openai

load_dotenv()
openai.api_key = os.environ.get('OPENAI_KEY')
completion = openai.Completion()

start_chat_log = '''Human: Hello, who are you?
AI: I am doing great. How can I help you today?
'''

La fonction load_dotenv() importe toutes les variables stockées dans un fichier .env en tant que variables d'environnement. Notez comment nous utilisons la variable OPENAI_KEY dans la ligne suivante pour initialiser OpenAI avec la clé. La variable completion maintient la liaison entre le client réel et le moteur. Il s'agit de l'objet que nous utiliserons pour envoyer des requêtes.

J'ai également ajouté une variable start_chat_log contenant les deux lignes qui amorcent le moteur. Une fois que le bot est opérationnel, je vous encourage à essayer différentes interactions dans cette variable pour voir comment il adapte ses réponses en conséquence.

Écrivons maintenant une fonction qui fait une requête GPT-3. Ajoutez la fonction suivante en bas de chatbot.py :

def ask(question, chat_log=None):
    if chat_log is None:
        chat_log = start_chat_log
    prompt = f'{chat_log}Human: {question}\nAI:'
    response = completion.create(
        prompt=prompt, engine="davinci", stop=['\nHuman'], temperature=0.9,
        top_p=1, frequency_penalty=0, presence_penalty=0.6, best_of=1,
        max_tokens=150)
    answer = response.choices[0].text.strip()
    return answer

La fonction ask() prend la question de l'utilisateur comme premier argument, suivi d'un historique des Chats facultatif. Si l'historique des Chats n'est pas fourni, la fonction utilise start_chat_log à la place.

La variable prompt est conçue pour contenir l'historique des Chats, suivi de la question de l'utilisateur, qui est précédée de Human :. Après la question de l'utilisateur, nous ajoutons la dernière ligne indiquant seulement AI:, qui est ce qui va donner au moteur GPT-3 la file d'attente pour générer une réponse à la question de l'utilisateur.

La fonction completion.create() est l'endroit où la requête au moteur GPT-3 est véritablement effectuée. Cette fonction utilise un certain nombre d'arguments, qui sont utilisés pour configurer la façon dont le moteur doit compléter le texte. Voici une brève description de ces arguments :

  • prompt : texte d'entrée.
  • engine : OpenAI a mis quatre moteurs d'achèvement de texte à disposition, nommés davinciadababbage et curie. Nous utilisons davinci, qui est le plus compétent des quatre.
  • stop : comme je l'ai mentionné plus tôt, le moteur GPT-3 ne comprend pas vraiment le texte, donc quand il complète le texte, il doit savoir quand arrêter. En donnant un arrêt à Human:, nous disons au moteur de générer juste le texte pour la ligne qui commence par AI:. Sans un marqueur d'arrêt, GPT-3 continuerait à générer du texte en écrivant plus de lignes pour l'utilisateur et l'IA.
  • temperature : un nombre compris entre 0 et 1 qui détermine le nombre de risques créatifs que le moteur prend lors de la génération de texte.
  • top_p : une autre façon de contrôler l'originalité et la créativité du texte généré.
  • frequency_penalty : un nombre compris entre 0 et 1. Plus cette valeur est élevée, plus le modèle fera un effort plus important pour ne pas se répéter.
  • presence_penalty : un nombre compris entre 0 et 1. Plus cette valeur est élevée, plus le modèle fera un effort plus important pour parler de nouveaux sujets.
  • max_tokens : longueur d'achèvement maximale.

Il ne s'agit pas des seules options possibles. Je vous recommande donc de consulter la documentation de référence OpenAI pour en savoir plus sur les méthodes de configuration de votre requête.

La réponse du moteur d'achèvement est un objet doté d'un attribut choices, qui est une liste d'achèvements. Nous n'en avons pas requêté plusieurs, donc la liste va avoir un seul élément. Cet élément est un dictionnaire Python avec une clé text qui contient le texte généré. Notre fonction prend ce texte, supprime tout espace blanc de début ou de fin et le renvoie à l'appelant. Comme mentionné ci-dessus, consultez la documentation de l'API pour obtenir des renseignements sur d'autres éléments de données inclus dans la réponse du GPT-3.

Commençons un shell Python et jouons avec la fonction ask() :

>>> from chatbot import ask
>>> ask('Who played Forrest Gump in the movie?')
'Oh my, that is a tough one! Forrest Gump was played by Tom Hanks.'
>>> ask('How long does it take to travel from Los Angeles to Dublin?')
'It takes about 12 hours to fly from Los Angeles to Dublin. You may want to fly through Heathrow Airport in London.'

Plutôt cool, non ? Ce qui nous manque, c'est la deuxième partie de notre algorithme, dans laquelle nous ajoutons une question et sa réponse à l'historique des Chats, afin que nous puissions l'utiliser dans la question suivante. Nous pouvons implémenter une deuxième fonction pour mettre à jour l'historique des Chats :

def append_interaction_to_chat_log(question, answer, chat_log=None):
    if chat_log is None:
        chat_log = start_chat_log
    return f'{chat_log}Human: {question}\nAI: {answer}\n'

Cette fonction prend une question et une réponse et les ajoute au bas de l'historique des Chats. L'historique des Chats mis à jour est renvoyé.

Nous pouvons maintenant avoir une conversation dans laquelle le contexte est préservé. Essayons ce qui suit dans une nouvelle session shell Python :

>>> from chatbot import ask, append_interaction_to_chat_log
>>> chat_log = None

>>> question = 'Who played Forrest Gump in the movie?'
>>> answer = ask(question, chat_log)
>>> answer
'Forrest Gump is a 1994 American romantic comedy-drama film based on the 1986 novel of the same name by Winston Groom. The film was directed by Robert Zemeckis and was adapted for the screen by Eric Roth. It stars Tom Hanks as Forrest Gump, for which he won the Academy Award for Best Actor, and was nominated for Best Picture.'

>>> chat_log = append_interaction_to_chat_log(question, answer, chat_log)

>>> question = 'Was he in any other great roles?'
>>> answer = ask(question, chat_log)
>>> answer
'He played the protagonist in The Green Mile (1999), a drama film based on the Stephen King novel of the same name.'

Ces deux fonctions sont tout ce dont nous avons besoin pour gérer notre chat. Dans les sections suivantes, nous allons les intégrer à la messagerie Twilio SMS.

Configuration de Twilio Programmable Messaging

Nous allons maintenant configurer un numéro de téléphone compatible Twilio SMS pour que le chatbot puisse l'utiliser. Si vous n'avez pas encore créé de compte Twilio gratuit, faites-le maintenant et connectez-vous.

Dans la console Twilio, sélectionnez Phone Numbers (Numéros de téléphone), puis cliquez sur le signe « + » rouge pour acheter un numéro Twilio. Dans l'écran Buy a Number (Acheter un numéro), vous pouvez sélectionner votre pays et cocher SMS parmi les fonctionnalités. Si vous souhaitez demander un numéro de votre région, vous pouvez saisir votre indicatif régional dans le champ Number (Numéro).

acheter un numéro de téléphone Twilio

Cliquez sur le bouton « Search » (Rechercher) pour voir les numéros disponibles, puis cliquez sur « Buy » (Acheter) pour le numéro que vous souhaitez dans les résultats. Après avoir confirmé votre achat, cliquez sur le bouton « Close » (Fermer). Notez que si vous utilisez un compte d'essai, les fonds de cet achat proviennent de votre crédit d'essai.

Félicitations, vous disposez désormais de votre propre numéro de téléphone programmable ! Munissez-vous de votre smartphone et envoyez un message texte à votre nouveau numéro pour vous assurer qu'il fonctionne. Vous devriez recevoir une réponse vous demandant de configurer votre numéro, ce que vous allez faire ensuite.

premier texte avec un webhook Twilio par défaut

L'API Twilio SMS utilise unwebhook pour notifier une application lorsqu'il y a un message entrant. La réponse automatique que vous avez reçue lorsque vous avez envoyé un message texte à votre numéro Twilio provient en fait d'un webhook par défaut qui est installé par Twilio sur votre numéro. L'application chatbot aura un nouveau webhook qui va remplacer celui par défaut.

Le framework Flask permet de définir très facilement un webhook. Vous trouverez ci-dessous une application squelette avec une définition de webhook. Copiez le code suivant dans un nouveau fichier appelé app.py :

from flask import Flask, request
from twilio.twiml.messaging_response import MessagingResponse

app = Flask(__name__)


@app.route('/bot', methods=['POST'])
def bot():
    incoming_msg = request.values['Body']

    # use the incoming message to generate the response here

    r = MessagingResponse()
    r.message('this is the response')
    return str(r)

Ce code crée une application Flask qui a un point de terminaison avec l'URL /bot. Lorsque Twilio est configuré pour connaître ce point de terminaison, il envoie une requête chaque fois qu'un SMS est reçu sur le numéro de téléphone que vous avez acheté précédemment. L'application peut lire le message entrant, effectuer un traitement et générer une réponse qui est renvoyée à la fin de la fonction.

Vous pouvez démarrer l'application ci-dessus comme suit :

(venv) $ flask run
 * Serving Flask app "app" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

L'application est maintenant en cours d'exécution sur votre ordinateur à l'URL http://localhost:5000, mais elle n'est pas accessible depuis Internet. L'étape suivante consiste à fournir une URL publique temporaire que nous pouvons donner à Twilio afin de permettre l'envoi des requêtes. Ce travail est réalisé par l'outil ngrok. Laissez l'application en cours d'exécution et ouvrez un deuxième terminal. Activez l'environnement virtuel sur ce terminal comme vous l'avez fait au début du tutoriel, puis entrez la commande suivante :

(venv) $ ngrok http 5000

Un écran similaire à celui-ci devrait s'afficher :

ngrok sur la ligne de commande

Notez les lignes commençant par « Forwarding ». Elles montrent les URL publiques que ngrok utilise pour rediriger les requêtes vers notre service, à la fois au format http:// et https://. Ce que nous devons faire maintenant, c'est dire à Twilio d'envoyer des notifications SMS entrantes à cette URL.

Revenez à la console Twilio, cliquez sur Phone Numbers (Numéros de téléphone), puis sur le numéro de téléphone que vous avez acheté ci-dessus. Faites défiler jusqu'à la section « Messaging » (Messagerie), copiez l'URL https:// de la sortie ngrok, puis collez-la dans le champ « A message comes in » (Un message arrive). Le point de terminaison que nous avons créé ci-dessus est exposé sous l'URL /bot, de sorte que /bot doit être ajouté à la fin de l'URL ngrok racine. Assurez-vous que la méthode de requête est définie sur HTTP POST. N'oubliez pas de cliquer sur le bouton bleu Save (Enregistrer) au bas de la page pour enregistrer ces modifications.

webhook de messagerie Twilio

Envoyez un autre SMS à votre numéro de téléphone Twilio pour obtenir la réponse fournie par l'application Flask :

réponse de Flask via Ngrok

Nous savons à présent comment exécuter le moteur GPT-3, et comment recevoir et répondre aux SMS avec Twilio. Dans la section suivante, nous allons intégrer les deux afin d'avoir un projet chatbot complet.

Chatbot SMS avec OpenAI et Twilio

Développons app.py pour envoyer des messages utilisateur à la fonction ask() que nous avons créée ci-dessus et pour tenir à jour l'historique du chat. Voici le contenu mis à jour de app.py :

from flask import Flask, request, session
from twilio.twiml.messaging_response import MessagingResponse
from chatbot import ask, append_interaction_to_chat_log

app = Flask(__name__)
app.config['SECRET_KEY'] = 'top-secret!'


@app.route('/bot', methods=['POST'])
def bot():
    incoming_msg = request.values['Body']
    chat_log = session.get('chat_log')

    answer = ask(incoming_msg, chat_log)
    session['chat_log'] = append_interaction_to_chat_log(incoming_msg, answer,
                                                         chat_log)

    r = MessagingResponse()
    r.message(answer)
    return str(r)

L'emplacement le plus pratique pour stocker l'historique des Chats avec un utilisateur est la variable session de Flask, qui utilise un cookie HTTP pour le stockage. Twilio fonctionne de la même manière qu'un navigateur Web à cet égard, et accepte, stocke (jusqu'à quatre heures) et renvoie les cookies pendant une conversation avec un utilisateur. S'il y a deux utilisateurs ou plus qui discutent avec le bot en même temps, chacun aura son propre cookie.

Étant donné que les cookies de session sont signés, une clé secrète doit être configurée pour l'application Flask. Pour des raisons de sécurité, vous devez remplacer la valeur de paramètre fictif que j'ai utilisée pour la clé secrète par quelque chose d'unique.

Le point de terminaison bot() commence par obtenir le message utilisateur comme auparavant et l'historique des Chats de la session. L'objet session utilise la syntaxe de dictionnaire familière, de sorte que session.get() retournera un historique des Chats précédemment stocké s'il existe, ou None si cet utilisateur n'a pas de session. Ceci est pratique, car les fonctions de chatbot.py utilisent l'historique des Chats standard si nous transmettons None.

L'appel de la fonction ask() fonctionne exactement comme avant. Nous transmettons le message de l'utilisateur et l'historique des Chats, et nous obtenons en retour la sortie du moteur GPT-3, qui est notre réponse.

La question et la réponse sont ensuite ajoutées à l'historique des Chats, et l'historique des Chats mis à jour est réenregistré dans la session utilisateur afin que l'historique complet des Chats soit utilisé lors de la prochaine interaction avec l'utilisateur.

Pour mettre fin à la fonction, la réponse est renvoyée en tant que réponse, et elle est renvoyée à l'utilisateur par SMS.

Prêt à essayer votre nouveau bot ? Si votre application Flask est toujours en cours d'exécution, arrêtez-la avec Ctrl-C, puis exécutez-la à nouveau pour qu'elle intègre les dernières mises à jour. Si ngrok n'est plus en cours d'exécution, accédez à votre deuxième terminal et redémarrez-le, puis suivez les instructions de la section précédente pour mettre à jour l'URL de votre webhook dans la console Twilio, puisque ngrok crée une URL différente à chaque exécution.

Avec l'application Flask et ngrok en cours d'exécution, vous êtes prêt à envoyer des SMS au bot. Envoyez un SMS avec votre première question au numéro de téléphone de Twilio comme vous l'avez fait avant, et dans quelques secondes la réponse devrait arriver. N'hésitez pas à essayer différents sujets pour le bot, il sait beaucoup de choses !

Dans l'exemple d'interaction suivant, il semble que le bot perd patience avec mes questions stupides, mais vous pouvez apprécier comment le maintien de l'historique des Chats dans la session utilisateur rend cette conversation très naturelle :

conversation complète avec un chatbot OpenAI

Conclusion

J'espère que ce projet vous a plu autant qu'à moi ! Les possibilités du moteur d'achèvement GPT-3 sont infinies. Je vous encourage donc à expérimenter avec lui en adaptant ce projet pour créer d'autres utilisations originales en plus de discuter.

N'hésitez pas à me faire part des projets que vous construisez !

Miguel Grinberg est développeur Python pour le contenu technique chez Twilio. Contactez-le à mgrinberg [at] twilio [dot] com si vous avez un projet Python que vous souhaitez partager sur ce blog !