Formation avancé sur le Framework Web Bottle pour Python


Télécharger Formation avancé sur le Framework Web Bottle pour Python

★★★★★★★★★★3.5 étoiles sur 5 basé sur 1 votes.
Votez ce document:

Télécharger aussi :


Formation avancé sur le Framework Web Bottle pour Python

...

1.1 Tutoriel

Ce didacticiel présente les concepts et les fonctionnalités du framework Web Bottle et couvre les sujets de base et avancés. Vous pouvez le lire du début à la fin ou l'utiliser plus tard comme référence. L'API générée automatiquement

La référence peut être intéressante pour vous aussi. Il couvre plus de détails, mais explique moins que ce tutoriel. Vous trouverez des solutions aux questions les plus courantes dans notre collection de recettes ou à la page Foire aux questions. Si vous avez besoin d’aide, rejoignez notre liste de diffusion ou rendez-nous visite sur notre canal IRC.

1.1.1 Installation

La bouteille ne dépend d'aucune bibliothèque externe. Vous pouvez simplement télécharger bottle.py dans votre répertoire de projet et commencer à coder:

$ wget https://bottlepy.org/bottle.py

Vous obtiendrez ainsi le dernier instantané de développement incluant toutes les nouvelles fonctionnalités. Si vous préférez un environnement plus stable, vous devriez vous en tenir aux versions stables. Ceux-ci sont disponibles sur PyPI et peuvent être installés via pip (recommandé), easy_install ou votre gestionnaire de paquets:

$ sudo pip installer la bouteille # recommandé

$ sudo easy_install bottle # alternative sans pip

$ sudo apt-get install python-bottle # fonctionne pour debian, ubuntu, ...

Dans les deux cas, vous aurez besoin de Python 2.7 ou version ultérieure (y compris 3.2+) pour exécuter les applications de flacon. Si vous ne disposez pas des autorisations nécessaires pour installer des packages sur l'ensemble du système ou si vous ne souhaitez tout simplement pas le faire, créez d'abord virtualenv:

$ virtualenv develop # Créer un environnement virtuel

$ source develop / bin / activate # Change le python par défaut en un virtuel (développement) $ pip install -U bottle # Installe la bouteille dans un environnement virtuel

Ou, si virtualenv n'est pas installé sur votre système:

$ wget https://raw.github.com/pypa/virtualenv/master/virtualenv.py

$ python virtualenv.py develop # Crée un environnement virtuel

$ source develop / bin / activate # Change le python par défaut en un virtuel (développement) $ pip install -U bottle # Installe la bouteille dans un environnement virtuel

1.1.2 Quickstart: «Hello World»

Ce tutoriel suppose que Bottle est installé ou copié dans le répertoire de votre projet. Commençons par un exemple très basique de «Hello World»:

de la route d'importation de bouteille, exécutez

@route ('/ hello')

def bonjour ():

retourner "Bonjour le monde!"

run (hôte = 'localhost', port = 8080, debug = True)

Ça y est. Exécutez ce script, visitez le site http: // localhost: 8080 / hello et vous verrez «Hello World!» Dans votre navigateur. Voici comment cela fonctionne:

Le décorateur route () lie un morceau de code à un chemin d'URL. Dans ce cas, nous relions le chemin / hello à la fonction hello (). C'est ce qu'on appelle un itinéraire (d'où le nom du décorateur) et constitue le concept le plus important de ce cadre. Vous pouvez définir autant de routes que vous le souhaitez. Chaque fois qu'un navigateur demande une URL, la fonction associée est appelée et la valeur renvoyée est renvoyée au navigateur. C'est aussi simple que ça.

L'appel run () de la dernière ligne démarre un serveur de développement intégré. Il fonctionne sur le port 8080 de l'hôte local et traite les demandes jusqu'à ce que vous appuyiez sur Control-c. Vous pouvez changer le serveur dorsal plus tard, mais pour le moment, un serveur de développement est tout ce dont nous avons besoin. Il ne nécessite aucune configuration et constitue un moyen extrêmement simple de mettre votre application en service pour des tests locaux.

Le mode de débogage est très utile au début du développement, mais doit être désactivé pour les applications publiques. Garde cela à l'esprit.

Ceci est juste une démonstration du concept de base de la façon dont les applications sont construites avec Bottle. Continuez à lire et vous verrez ce qui est possible.

L'application par défaut

Par souci de simplicité, la plupart des exemples de ce tutoriel utilisent un décorateur route () au niveau du module pour définir des itinéraires. Cela ajoute des itinéraires à une «application par défaut» globale, une instance de Bottle créée automatiquement la première fois que vous appelez route (). Plusieurs autres décorateurs et fonctions au niveau du module se rapportent à cette application par défaut, mais si vous préférez une approche plus orientée objet et que vous ne vous occupez pas de la frappe supplémentaire, vous pouvez créer un objet d’application distinct et l’utiliser au lieu de l’objet global:

de l'importation de la bouteille

app = Bottle () @ app.route ('/ hello')

def bonjour ():

retourner "Bonjour le monde!"

exécuter (app, hôte = 'localhost', port = 8080)

L'approche orientée objet est décrite plus en détail dans la section Application par défaut. N'oubliez pas que vous avez le choix.

1.1.3 Routage des demandes

Dans le dernier chapitre, nous avons construit une application Web très simple avec un seul itinéraire. Voici à nouveau la partie routage de l'exemple «Hello World»:

@route ('/ hello')

def bonjour ():

retourner "Bonjour le monde!"

Le décorateur route () lie un chemin d’URL à une fonction de rappel et ajoute une nouvelle route à l’application par défaut. Une application avec un seul itinéraire est plutôt ennuyeuse. Ajoutons un peu plus (ne pas oublier de l'importation de bouteilles

modèle):

@route('/')

@route ('/ hello / <nom>')

def greet (name = 'Stranger'):

modèle de retour ('Bonjour {{nom}}, comment ça va?', nom = nom)

Cet exemple montre deux choses: vous pouvez lier plusieurs routes à un seul rappel, vous pouvez ajouter des caractères génériques à des URL et y accéder via des arguments de mots clés.

Itinéraires dynamiques

Les itinéraires contenant des caractères génériques sont appelés itinéraires dynamiques (par opposition aux itinéraires statiques) et correspondent à plusieurs URL en même temps. Un caractère générique simple consiste en un nom placé entre crochets (par exemple, <nom>) et accepte un ou plusieurs caractères jusqu'à la prochaine barre oblique (/). Par exemple, route / hello / <nom> accepte les demandes pour / hello / alice ainsi que / hello / bob, mais pas pour / hello, / hello / ou / hello / mr / smith.

Chaque caractère générique transmet la partie couverte de l'URL en tant qu'argument de mot clé au rappel de demande. Vous pouvez les utiliser immédiatement et implémenter facilement des URL RESTful, jolies et significatives. Voici d’autres exemples avec les URL correspondantes:

@route ('/ wiki / <nom de page>') # correspond à / wiki / Learning_Python

def show_wiki_page (nom de page):

...

@route ('/ <action> / <utilisateur>') # correspond / suivre / defnull

def user_api (action, utilisateur):



...

Les filtres peuvent être utilisés pour définir des caractères génériques plus spécifiques et / ou transformer la partie couverte de l'URL avant qu'elle ne soit transmise au rappel. Un caractère générique filtré est déclaré comme <nom: filtre> ou <nom: filtre: config>. La syntaxe de la partie facultative config dépend du filtre utilisé.

Les filtres suivants sont implémentés par défaut et d'autres peuvent être ajoutés:

  • : int ne fait correspondre que les chiffres (signés) et convertit la valeur en entier.
  • : float similaire à: int mais pour les nombres décimaux.
  • : chemin correspond à tous les caractères, y compris le caractère barre oblique, d'une manière non gourmande et peut être utilisé pour faire correspondre plusieurs segments de chemin.
  • : re vous permet de spécifier une expression régulière personnalisée dans le champ config. La valeur correspondante n'est pas modifiée.

Voyons quelques exemples pratiques:

@route ('/ object / <id: int>')

def callback (id):

assert isinstance (id, int)

@route ('/ show / <name: re: [a-z] +>')

def callback (nom):

assert name.isalpha ()

@route ('/ static / <path: path>')

def callback (path):

retourne static_file (chemin, ...)

Vous pouvez également ajouter vos propres filtres. Voir Request Routing pour plus de détails.

Méthodes de demande HTTP

Le protocole HTTP définit plusieurs méthodes de requête (parfois appelées «verbes») pour différentes tâches. GET est la valeur par défaut pour toutes les routes sans aucune autre méthode spécifiée. Ces itinéraires correspondront uniquement aux demandes GET. Pour gérer d'autres méthodes telles que POST, PUT, DELETE ou PATCH, ajoutez un argument de mot clé à la décoratrice de route () ou utilisez l'un des cinq décorateurs alternatifs: get (), post (), put (), delete () ou pièce().

La méthode POST est couramment utilisée pour la soumission de formulaires HTML. Cet exemple montre comment gérer un formulaire de connexion à l'aide de POST:

à partir de l’importation de la bouteille

@get ('/ login') # ou @route ('/ login')

def login ():

revenir '''

<form action = "/ login" method = "post">

Nom d'utilisateur: <nom d'entrée = "nom d'utilisateur" type = "texte" />

Mot de passe: <nom d'entrée = "mot de passe" type = "mot de passe" />

<input value = "Login" type = "submit" />

</ form>

'' '

@post ('/ login') # ou @route ('/ login', method = 'POST')

def do_login ():

nom d'utilisateur = request.forms.get ('nom d'utilisateur')

password = request.forms.get ('mot de passe')

si check_login (nom d'utilisateur, mot de passe):

retourner "<p> Vos informations de connexion étaient correctes. </ p>"

autre:

retourner "<p> Échec de la connexion. </ p>"

Dans cet exemple, l'URL / login est liée à deux rappels distincts, l'un pour les demandes GET et l'autre pour les demandes POST. Le premier affiche un formulaire HTML à l'utilisateur. Le second rappel est appelé lors de la soumission d'un formulaire et vérifie les informations de connexion que l'utilisateur a entrées dans le formulaire. L’utilisation de Request.forms est décrite plus en détail dans

Section de demande de données.

Méthodes spéciales: HEAD et ANY

La méthode HEAD est utilisée pour demander une réponse identique à celle qui correspondrait à une demande GET, mais sans le corps de la réponse. Ceci est utile pour récupérer des méta-informations sur une ressource sans avoir à télécharger le document entier. Bottle traite automatiquement ces demandes en revenant à la route GET correspondante et en coupant le corps de la demande, le cas échéant. Vous n’avez pas à spécifier d’itinéraires HEAD vous-même.

En outre, la méthode ANY non standard fonctionne comme un secours de priorité basse: les itinéraires écoutés par ANY correspondront aux demandes indépendamment de leur méthode HTTP mais uniquement si aucun autre itinéraire plus spécifique n'est défini. Ceci est utile pour les routes de proxy qui redirigent les demandes vers des sous-applications plus spécifiques.

Pour résumer: les demandes HEAD retombent sur les itinéraires GET et toutes les demandes sur TOUT itinéraires, mais uniquement s'il n'y a pas d'itinéraire correspondant pour la méthode de demande d'origine. C'est aussi simple que ça.

Routage des fichiers statiques

Les fichiers statiques tels que les images ou les fichiers CSS ne sont pas servis automatiquement. Vous devez ajouter une route et un rappel pour contrôler quels fichiers sont servis et où les trouver: from bottle import static_file

@route ('/ static / <nom_fichier>')

def server_static (nom de fichier):

retourne static_file (nomfichier, racine = '/ chemin / vers / votre / statique / fichiers')

La fonction static_file () est une aide qui permet de servir les fichiers de manière sûre et pratique (voir Fichiers statiques). Cet exemple est limité aux fichiers directement dans le répertoire / path / to / your / static / files, car le caractère générique <nomfichier> ne correspond à aucun chemin avec une barre oblique. Pour servir des fichiers dans des sous-répertoires, changez le caractère générique pour utiliser le chemin

filtre:

@route ('/ static / <chemin du fichier: chemin>')

def server_static (chemin du fichier):

retourne static_file (chemin du fichier, racine = '/ chemin / vers / votre / statique / fichiers')

Soyez prudent lorsque vous spécifiez un chemin racine relatif tel que root = '. / Static / files'. Le répertoire de travail (./) et le répertoire du projet ne sont pas toujours les mêmes.

Pages d'erreur

En cas de problème, Bottle affiche une page d'erreur informative mais assez simple. Vous pouvez remplacer la valeur par défaut pour un code de statut HTTP spécifique avec le décorateur error ():

de l'erreur d'importation de bouteille

@Erreur 404)

def error404 (error):

retourner 'Rien ici, désolé'

À partir de maintenant, les erreurs 404 Fichier non trouvé afficheront une page d'erreur personnalisée à l'intention de l'utilisateur. Le seul paramètre transmis au gestionnaire d'erreurs est une instance de HTTPError. En dehors de cela, un gestionnaire d'erreurs est assez similaire à un rappel de demande régulier. Vous pouvez lire à partir de la demande, écrire dans la réponse et renvoyer tout type de données pris en charge, à l'exception des instances HTTPError.

Les gestionnaires d'erreur ne sont utilisés que si votre application renvoie ou déclenche une exception HTTPError (c'est ce que fait abort ()).

Le changement de Request.status ou le renvoi de HTTPResponse ne déclenchera pas le gestionnaire d’erreur.

1.1.4 Générer du contenu



En WSGI pur, la gamme de types que vous pouvez renvoyer à partir de votre application est très limitée. Les demandes doivent renvoyer un

iterable céder des chaînes d'octets. Vous pouvez renvoyer une chaîne (car les chaînes sont itératives), mais la plupart des serveurs transmettent votre contenu caractère par caractère. Les chaînes Unicode ne sont pas autorisées du tout. Ce n'est pas très pratique.

La bouteille est beaucoup plus souple et prend en charge une grande variété de types. Il ajoute même si possible un en-tête Content-Length et code unicode automatiquement, pour que vous n'ayez pas à le faire. Vous trouverez ci-dessous une liste des types de données que vous pouvez renvoyer à partir des rappels de votre application, ainsi qu'une brève description de la façon dont ils sont gérés par la structure:

Dictionnaires Comme mentionné ci-dessus, les dictionnaires Python (ou leurs sous-classes) sont automatiquement transformés en chaînes JSON et renvoyés au navigateur avec l'en-tête Content-Type défini sur application / json.

Cela facilite l'implémentation d'API basées sur JSON. Les formats de données autres que JSON sont également pris en charge. Voir le tutoriel-output-filter pour en savoir plus.

Chaînes vides, False, None ou autres valeurs non vraies: elles produisent une sortie vide avec

En-tête Content-Length défini sur 0.

Chaînes Unicode Les chaînes Unicode (ou les éléments itérables générant des chaînes Unicode) sont automatiquement codés avec le codec spécifié dans l'en-tête Content-Type (utf8 par défaut), puis traités comme des chaînes d'octets normales (voir ci-dessous).

Chaînes d'octets Bottle renvoie les chaînes dans leur ensemble (au lieu d'itérer chaque caractère) et ajoute un en-tête Content-Length basé sur la longueur de la chaîne. Les listes de chaînes d'octets sont jointes en premier. Les autres itérables donnant des chaînes d'octets ne sont pas joints car ils risquent de devenir trop volumineux pour tenir en mémoire. L'en-tête Content-Length n'est pas défini dans ce cas.

Les instances de HTTPError ou HTTPResponse Le renvoi de celles-ci a le même effet que lors de leur levée en tant qu'exception. Dans le cas d'une erreur HTTPError, le gestionnaire d'erreurs est appliqué. Voir Pages d'erreur pour plus de détails.

Objets fichier Tout ce qui a une méthode .read () est traité comme un fichier ou un objet de type fichier et transmis à l'appelable wsgi.file_wrapper défini par la structure de serveur WSGI. Certaines implémentations de serveur WSGI peuvent utiliser des appels système optimisés (sendfile) pour transmettre les fichiers plus efficacement. Dans d'autres cas, cela se répète sur les morceaux qui entrent dans la mémoire. Les en-têtes facultatifs tels que Content-Length ou Content-Type ne sont pas définis automatiquement. Utilisez send_file () si possible. Voir Fichiers statiques pour plus de détails.

Iterables et générateurs Vous êtes autorisé à utiliser le rendement dans vos rappels ou à renvoyer un itératif, à condition que l'itérable génère des chaînes d'octets, des chaînes unicode, des instances HTTPError ou HTTPResponse. Les iterables imbriqués ne sont pas supportés, désolé. Veuillez noter que le code d'état HTTP et les en-têtes sont envoyés au navigateur dès que l'itérable donne sa première valeur non vide. Changer ces derniers n'a aucun effet.

L'ordre de cette liste est important. Vous pouvez par exemple renvoyer une sous-classe de str avec une méthode read (). Il est toujours traité comme une chaîne au lieu d'un fichier, car les chaînes sont traitées en premier.

Changer le codage par défaut

Bottle utilise le paramètre charset de l'en-tête Content-Type pour décider comment coder les chaînes unicode. Par défaut, cet en-tête est text / html; charset = UTF8 et peut être modifié à l'aide de l'attribut Response.content_type ou en définissant l'attribut Response.charset directement. (L'objet Response est décrit dans la section L'objet Response.) À partir de la réponse d'importation de flacon

@route ('/ iso')

def get_iso ():

response.charset = 'ISO-8859-15'

Cela vous sera envoyé avec l'encodage ISO-8859-15. '

@route ('/ latin9')

def get_latin ():

response.content_type = 'text / html; charset = latin9 'retour L'ISO-8859-15 est également appelé latin9.'

Dans de rares cas, les noms de codage Python diffèrent de ceux pris en charge par la spécification HTTP. Ensuite, vous devez faire les deux: d'abord, définissez l'en-tête Response.content_type (qui est envoyé au client sous forme inchangée), puis définissez l'attribut Response.charset (qui est utilisé pour coder unicode).

Fichiers statiques

Vous pouvez directement renvoyer des objets de fichier, mais static_file () est le moyen recommandé de servir des fichiers statiques. Il détecte automatiquement un type mime, ajoute un en-tête Last-Modified, limite les chemins d'accès à un répertoire racine pour des raisons de sécurité et génère les réponses d'erreur appropriées (403 sur les erreurs d'autorisation, 404 sur les fichiers manquants). Il prend même en charge l'en-tête If-Modified-Since et génère éventuellement une réponse 304 Non modifié. Vous pouvez passer un type MIME personnalisé pour désactiver les devinettes.

de la bouteille importez static_file

@route ('/ images / <nomfichier: re:. * \. png>')

def send_image (nom du fichier):

retourne static_file (nom_fichier, racine = '/ chemin / vers / image / fichiers', type MIME = 'image / png')

@route ('/ static / <nomfichier: chemin>')

def send_static (nom du fichier):

retourne static_file (nomfichier, racine = '/ chemin / vers / statique / fichiers')

Vous pouvez augmenter la valeur de retour de static_file () comme exception si vous en avez vraiment besoin.

Téléchargement forcé

La plupart des navigateurs tentent d'ouvrir les fichiers téléchargés si le type MIME est connu et attribué à une application (par exemple, des fichiers PDF).

Si ce n'est pas ce que vous voulez, vous pouvez forcer une boîte de dialogue de téléchargement et même suggérer un nom de fichier à l'utilisateur:

@route ('/ download / <nom du fichier: chemin>')

téléchargement de def (nom de fichier):

retourne static_file (nom_fichier, racine = '/ chemin / vers / statique / fichiers', download = nomfichier)

Si le paramètre download est uniquement True, le nom de fichier d'origine est utilisé.

Erreurs HTTP et redirections

La fonction abort () est un raccourci pour générer des pages d'erreur HTTP.

de la voie d'importation de bouteille, avorter

@route ('/ restricted')

def restreint ():

abort (401, "Désolé, accès refusé.")

Pour rediriger un client vers une autre URL, vous pouvez envoyer une réponse 303 Voir Autre avec l'en-tête Location défini sur la nouvelle URL. redirect () le fait pour vous:

de la redirection d'importation de bouteilles

@route ('/ wrong / url')

def faux ():

redirection ("/ right / url")



12