Maison  >  Article  >  développement back-end  >  Notes de lecture du code source de la bouteille (1) : WSGI

Notes de lecture du code source de la bouteille (1) : WSGI

巴扎黑
巴扎黑original
2017-06-23 15:06:292396parcourir

Avant-propos

Bottle est un framework web Python. L'ensemble du framework ne contient qu'un seul fichier, moins de 4 000 lignes de code et aucune dépendance autre que la bibliothèque standard Python. Cependant, il inclut des fonctions communes aux frameworks Web telles que le routage, les modèles et les plug-ins. Il n'y a pas de meilleur moment que de lire le code source de Bottle pour comprendre ce qu'est un framework web et comment il fonctionne. Puisque Bottle est un framework qui prend en charge WSGI, avant de lire le code source, comprenons d'abord ce qu'est WSGI.

Remarque : La version de Bottle utilisée dans cet article est la 0.12.13.

WSGI

Les serveurs Web généraux ne peuvent gérer que des pages statiques. Si du contenu dynamique est impliqué, le serveur doit interagir avec des langages serveur tels que Java/Python/Ruby et leur transmettre le contenu pour traitement. Étant donné que la plupart des serveurs Web sont écrits en C, ils ne peuvent pas exécuter directement le langage du serveur, un pont est donc nécessaire entre les deux (dans les applications pratiques, un serveur d'applications est généralement ajouté entre le serveur Web et l'application WSGI pour prendre en charge WSGI). En Python, WSGI est un tel pont. La mise en œuvre de WSGI est divisée en deux parties, l'une est le serveur et l'autre est l'application. Voyons à quoi ressemble chacun d’eux et comment les deux fonctionnent ensemble.

 1 class Server: 2  3     def __init__(self, server_address): 4         self.server_address = server_address 5  6     def set_app(self, application): 7         self.app = application 8  9     def serve_forever(self):10         while True:11             # socket.accept()12             if request_comein():13                 self.handle_request()14 15     def handle_request(self):16         request_data = self.get_request()17         self.parse_request(request_data)18         environ = self.get_environ()19         result = self.application(environ, self.start_response)20         self.send_response(result)21 22     def start_response(self, status, headers, exc_info):23         pass24 25     def get_environ(self):26         pass27 28     def get_request(self):29         pass30 31     def parse_request(self, text):32         pass33 34     def send_response(self, message):35         pass36 37 38 def make_server(host, port, app, server=Server):39     server = server((host, port))40     server.set_app(app)41     return server42 43 def simple_app(environ, start_response):44     status = '200 OK'45     response_headers = [('Content-type', 'text/plain')]46     start_response(status, response_headers)47     return 'Hello World!'48 49 if __name__ == '__main__':50     server = make_server('localhost', 8080, simple_app)51     server.serve_forever()

Limité par l'espace, ce modèle de serveur omet de nombreux détails. Si vous souhaitez un serveur WSGI simple et fonctionnel, vous pouvez vous référer à Let's Build ici A. Serveur Web.Partie 2.

Après avoir reçu la requête, le serveur analyse les informations contenues dans le message de requête et enregistre le résultat dans un dictionnaire nommé environ. Ensuite, l'application d'application (environ, start_response) est appelée avec environ et la fonction start_response qui traite les informations d'en-tête en tant que paramètres. Enfin, les résultats de l'application sont composés dans une nouvelle réponse et renvoyés au client.

Côté application, une application WSGI est un objet appelable. Il peut s'agir d'une fonction, d'une méthode, d'une classe ou d'une instance avec une méthode __call__. L'application ci-dessus est une fonction.

Lorsque divers serveurs et applications/frameworks sont développés conformément aux normes WSGI, nous pouvons librement combiner différents serveurs et frameworks en fonction de nos besoins.

L'application la plus simple de Bottle

Après avoir brièvement compris WSGI, nous revenons à Bottle pour observer à quoi ressemble une application Bottle, comment l'exécuter et comment nous différence entre les modèles.

1 from bottle import Bottle, run2 3 app = Bottle()4 5 @app.route('/hello')6 def hello():7     return 'Hello World!'8 9 run(app, host='localhost', port=8080, server='wsgiref')

Maintenant, exécutez ce programme et utilisez le navigateur pour accéder à l'adresse 'localhost:8080/hello' et vous verrez 'Hello World !'

1. Contrairement à l'application ci-dessus, l'application Bottle est une instance. Selon la réglementation WSGI, l'objet Bottle doit implémenter la méthode __call__ :

1 def __call__(self, environ, start_response):2     ''' Each instance of :class:'Bottle' is a WSGI application. '''3     return self.wsgi(environ, start_response)

Cette méthode Bottle.wsgi est donc l'entrée permettant au serveur d'appeler l'objet Bottle.wsgi. Application Bottle, et c'est également le point d'entrée permettant au serveur d'appeler l'application Bottle. Notre point d'entrée pour la lecture du code source.

2. @app.route() Ce décorateur lie une fonction à une URL. Lorsque nous accédons à 'localhost:8080/hello', la fonction hello sera appelée.

3. Le serveur par défaut de Bottle est wsgiref (une simple implémentation de WSGI dans la bibliothèque standard Python). Bien entendu, Bottle a également écrit des adaptateurs pour de nombreux serveurs. Il vous suffit de modifier la valeur de server et la fonction run() trouvera l'adaptateur correspondant en fonction du nom du serveur. Pas besoin d'écrire du code supplémentaire.

fonction d'exécution et code pièce de l'adaptateur :

 1 def run(app=None, server='wsgiref', host='127.0.0.1', port=8080, 2         interval=1, reloader=False, quiet=False, plugins=None, 3         debug=None, **kargs): 4     if server in server_names: 5         server = server_names.get(server) 6     if isinstance(server, basestring): 7         server = load(server) 8     if isinstance(server, type): 9         server = server(host=host, port=port, **kargs)10     if not isinstance(server, ServerAdapter):11         raise ValueError("Unknown or unsupported server: %r" % server)12     ...13     server.run(app)14 15 class MeinheldServer(ServerAdapter):16     def run(self, handler):17         from meinheld import server18         server.listen((self.host, self.port))19         server.run(handler)

Enfin

dans cet article , nous avons brièvement présenté la manière dont les serveurs et les applications interagissent sous la norme WSGI. Dans le prochain article, nous continuerons à nous concentrer sur cette application la plus simple et à parler des fonctions de routage liées à @app.route().

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn