Skip to content
This repository was archived by the owner on May 7, 2021. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
9f3d73a
Initialisation du sujet API REST HUG
charlyDevor Mar 16, 2017
fe59f4f
Titre du document
charlyDevor Mar 16, 2017
9b47378
Chapitre sur le HUG
charlyDevor Mar 24, 2017
05eea0e
espace
charlyDevor Mar 25, 2017
4acb811
grr
charlyDevor Mar 25, 2017
1ac764b
**kwargs
charlyDevor Mar 25, 2017
ef8b42c
suppression
charlyDevor Mar 25, 2017
078dd62
modif
charlyDevor Jun 14, 2017
4031aac
Create index.rst
charlyDevor Jun 14, 2017
c443da1
Create index.rst
charlyDevor Jun 14, 2017
7d7860e
Create index.rst
charlyDevor Jun 14, 2017
8801f14
Add files via upload
charlyDevor Jun 14, 2017
f1fb9fa
logo
charlyDevor Jun 14, 2017
2073627
Create index.rst
charlyDevor Jun 14, 2017
e7a2639
Terme annotation
charlyDevor Jun 14, 2017
5c47eba
Update index.rst
charlyDevor Jun 14, 2017
ee08666
Create index.rst
charlyDevor Jun 14, 2017
9a4afc6
Create index.rst
charlyDevor Jun 14, 2017
815bc5b
Create index.rst
charlyDevor Jun 14, 2017
519506a
Create index.rst
charlyDevor Jun 14, 2017
a35db90
Create somme.py
charlyDevor Jun 14, 2017
cb452f2
Create index.rst
charlyDevor Jun 14, 2017
cf44fea
Create index.rst
charlyDevor Jun 14, 2017
9df5b23
Create index.rst
charlyDevor Jun 14, 2017
ff9540c
Create index.rst
charlyDevor Jun 14, 2017
8bdb9cf
Create index.rst
charlyDevor Jun 14, 2017
a32523c
Merge branch 'master' into hug
charlyDevor Jun 14, 2017
705de2f
Update somme.py
charlyDevor Jun 14, 2017
fa05fa5
Update somme.py
charlyDevor Jun 14, 2017
9b2899b
Delete somme.py
charlyDevor Jun 14, 2017
a21c778
content-type
charlyDevor Jun 14, 2017
44f5f54
Create index.rst
charlyDevor Jun 14, 2017
d9b95dd
Create index.rst
charlyDevor Jun 14, 2017
f5c21e0
Create index.rst
charlyDevor Jun 14, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added source/hug/hug.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
160 changes: 115 additions & 45 deletions source/hug/index.rst
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
.. _hug-tutorial:


=======
``hug``
=======


.. image:: hug.png
:scale: 50%
:align: center
:alt: hug


Par Charles Ombang Ndo [#co]_

Introduction
Expand All @@ -17,10 +25,11 @@ possibles et les normes d'utilisation. La plupart des applications actuelles
offrent ces *web services* plus connues sous RESTful web service.

Dans l'univers Python, la bibliothèque hug_ est un outil assez puissant
permettant d'implémenter une API. L'utilisation de la technologie ``hug`` pour
permettant d'implémenter une API. L'utilisation de la technologie hug_ pour
créer des APIs en Python est motivée par de nombreux avantages qui seront
détaillés dans un chapitre dédié.


RESTful web service et ``hug``
------------------------------

Expand All @@ -36,10 +45,14 @@ tout le temps les mêmes.
Le concept RESTful web service repose sur les ressources qui sont représentées
par les `URLs`. Le client envoie des requêtes via ces URLs au moyen des
méthodes du protocole HTTP, ce sont les verbes:
- GET: récupération de données,
- POST: ajout de données
- PUT: modifications de données
- DELETE: suppression de données.


- GET: récupération de données,
- POST: ajout de données
- PUT: modifications de données
- DELETE: suppression de données.



Les formats d'échanges sont nombreux. Dans ce chapitre, nous resterons sur du
:ref:`JSON <json-tutorial>`.
Expand All @@ -48,10 +61,11 @@ Pourquoi choisir ``hug``
------------------------

Les très célèbres frameworks que sont Flask_ et Django_ sont bousculés par les
performances qu'apportent hug. hug permet d'écrire une API de manière
simplifiée. Les API implémentées dans d'autres frameworks peuvent l'être en
performances qu'apportent hug_. La bibliothèque hug_ permet d'écrire une API de manière
simplifiée. Les APIs implémentées dans d'autres frameworks peuvent l'être en
quelques lignes avec hug. hug supporte le versioning, il permet la
documentation par le code et hug intègre la validation des données.
documentation par le code et il intègre la validation des données.


Fonctionnement
==============
Expand Down Expand Up @@ -87,9 +101,11 @@ L'exécution du code ci-dessus via la commande.
$ hug -f somme.py

hug_ lance le serveur sur le port 8000. En entrant l'adresse
``http://localhost:8000`` on a une réponse au format JSON. Dans notre exemple
``http://localhost:8000`` on a une réponse au format :ref:`JSON <json-tutorial>`. Dans notre exemple

on obtient:


.. code-block:: json

{
Expand Down Expand Up @@ -118,15 +134,21 @@ on obtient:
}
}

On peut remarquer que la documentation est très claire, la clé `overview` nous renseigne sur l'objectif de notre API, La clé usage renseigne sur le type de données renvoyées par l'API, dans notre cas, la ligne de code @hug.get() indique qu'il s'agit d'une requête GET. La suite du bloc JSON ci-dessus nous renseigne sur les paramètres des l'API, leurs types et le format de retour.

Maintenant pour voir le résultat de notre (petite) API, il suffit d'entrer dans le navigateur l'adresse suivante localhost:8000/somme?val1=..&val2= .. il suffit de passer les valeurs aux paramètres.
On peut remarquer que la documentation est très claire, la clé overview nous renseigne sur l'objectif de notre API, La clé usage renseigne sur le type de données renvoyées par l'API, dans notre cas, la ligne de code ``@hug.get()`` indique qu'il s'agit d'une requête GET. La suite du bloc :ref:`JSON <json-tutorial>` ci-dessus nous renseigne sur les paramètres de l'API, leurs types et le format de retour.

Maintenant pour voir le résultat de notre (petite) API, il suffit d'entrer dans le navigateur l'adresse suivante:
``localhost:8000/somme?val1=..&val2= ..`` et de passer les valeurs aux paramètres.

Important: Les APIs écrit avec hug_ peuvent être accédées depuis la console, pour cela, il suffit de rajouter ``@hug.cli()``
comme nous l'avons fait avec ``@hug.get()``.

hug et le versioning

Hug et les versions
====================

Comme souligné auparavant, hug supporte et gère très bien le versioning. On peut avoir plusieurs versions de l'API dans la même application.
Comme souligné auparavant, hug_ supporte et gère très bien le versioning. On peut avoir plusieurs versions de l'API dans la même application.



.. code-block:: python3
Expand All @@ -144,7 +166,8 @@ Comme souligné auparavant, hug supporte et gère très bien le versioning. On p
return "Echo: {text}".format(**locals())


Le code ci-dessus montre la façon dont hug gère le versioning. Il suffit pour cela d'ajouter dans la méthode GET les versions que l'on veut. C'est une fois de plus assez claire, simple et compréhensible.

Le code ci-dessus montre la façon dont hug_ gère le versioning. Il suffit pour cela d'ajouter dans la méthode GET les versions que l'on veut. C'est une fois de plus assez claire, simple et compréhensible.

On peut déduire du code précédent que l'on a 4 versions. Pour le vérifier, il suffit de mettre dans le navigateur l'adresse http://localhost:8000, on a alors la documentation au format JSON suivante:

Expand Down Expand Up @@ -179,46 +202,50 @@ On peut déduire du code précédent que l'on a 4 versions. Pour le vérifier, i
}
}

Si on compare ce rendu JSON au précédent, on remarque la présence du champ

Si on compare ce rendu :ref:`JSON <json-tutorial>` au précédent, on remarque la présence du champ
``version``. La clé ``version`` de valeur 4 indique la version actuelle de l'API et
la clé ``versions`` prend en valeur un tableau listant les différentes versions
de notre API. Pour tester le bon fonctionnement du versioning, on peut écrire
<http://localhost:8000/v1/echo?text=toto>. Dans cette URL, on spécifie la version
http://localhost:8000/v1/echo?text=toto. Dans cette URL, on spécifie la version
que l'on souhaite utiliser, ici la version v1. En sortie on aura ``toto``, ce qui
correspond bien à la sortie attendue de la version 1. En changeant dans l'URL
juste la version en la remplaçant par v2, v2 ou v4, la sortie est naturellement
celle attendue suivant la version indiquée ``Echo:toto``.


*Type annotation* et validation
===============================
Validation automatique des données
==================================

Il est possible d'ajouter des fonctions aux paramètres de nos méthodes, pour
expliciter comment ils sont validés et transcris en type python, on parle de
type annotation. ``argument:type``. L'avantage de l'utilisation d'une telle
expliciter comment ils sont validés et transcris en type python. Pour cela, il suffit
de mettre les arguments sous la forme suivante: ``argument:type``. L'avantage de l'utilisation d'une telle
spécification est de clairement indiquer au niveau de la documentation le type
de données attendues.
de données attendues. Ceci est connu sous le terme annotations_ en python.

.. code-block:: python3

"""Test des types annotations"""
"""Test de la validation automatique des données"""
import hug

@hug.get()
def annota(text:int):
return text

Le code ci-dessus montre l'utilisation des annotations. l'argument de la
fonction ``annota(...)`` est suivi du type int soit text::int. On comprend

Le code ci-dessus montre comment valider les données automatiquement. L'argument de la
fonction ``annota(...)`` est suivi du type int soit ``text::int``. On comprend
aisément que l'argument text est de type int. Vérifions la sortie suivant
l'adresse <http://localhost:8000>
l'adresse <http://localhost:8000>.



.. code-block:: json

{
"404": "The API call you tried to make was not defined. Here's a definition of the API to help you get going :)",
"documentation": {
"overview": "Test des types annotations",
"overview": "Test de la validation automatique des données",
"handlers": {
"/annota": {
"GET": {
Expand All @@ -237,10 +264,11 @@ l'adresse <http://localhost:8000>
}
}


On voit bien dans le bloc inputs la clé type, on peut clairement voir que
l'entrée est de type int.

Si on entre l'adresse <http://localhost:8000/annota?text=salut> on a en retour
Si on entre l'adresse http://localhost:8000/annota?text=salut on a en retour
une belle erreur comme celle ci-dessous:

.. code-block:: json
Expand All @@ -251,16 +279,18 @@ une belle erreur comme celle ci-dessous:
}
}

Il est important de noter que les annotations permettent implicitement de faire
la validation automatique des données.

Cette technique qu'apporte la bibliothèque hug_ permet de valider les données automatiquement. Cela est fait
implicitement.



Les directives
==============

Les directives sont globalement des arguments enregistrés pour fournir
automatiquement des valeurs. Un exemple serait meilleur pour expliquer le rôle
des directives. hug possède des directives prédéfinies, mais il donne la
des directives. hug_ possède des directives prédéfinies, mais il donne la
possibilité de créer des directives personnalisées.

.. code-block:: python3
Expand Down Expand Up @@ -337,38 +367,76 @@ comme le montre le code ci-dessous

.. code-block:: python3

@hug.format.content_type('file/text')
@hug.format.content_type('text/plain')
def format_as_text(data, request=None, response=None):
return str(content).encode('utf-8')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


Le format par défaut est le :ref:`JSON <json-tutorial>`. L'une des technique pour définir un nouveau format par défaut est

``hug.API(__name__).http.output_format = hug.<format cible>`` par exemple format_cible ``output_format.html``

.. warning::
Si on souhaite un format pour une url spécifique et pas toutes les urls, par exemple pour notre méthode somme, on
veut que le format soit en ``html`` on fera:

le ``Content-Type`` nommé ``file/text`` n'existe pas. Ce n'est pas donc pas
un exemple utilisable en l'état.

.. Yoan
.. code-block:: python3

Le Routing
"""Simple application effectuant une somme de deux nombres"""
import hug

@hug.get(output = hug.output = hug.output_format.html)
def somme(val1, val2):
"""Retourne la somme des deux nombres passés en paramètre"""
return "<h1>{}</h1>".format(val1 + val2)


donc il suffit de spécifier le format dans le get ``@hug.get(output = hug.output = hug.<format cible>)``.

Le routage
----------

C'est la notion qu'on retrouve dans la plupart des frameworks. Il s'agit de
définir des chemins, urls d'accès aux données. `La documentation officielle
<http://www.hug.rest/website/learn/routing>`_ détaille la notion de *Routing*
de façon plus élaborée et plus large.
définir des chemins, urls d'accès aux données. Le mécanisme est simplifié, il y'a plusieurs manières
de faire le routage avec la bibliothèque hug_.

.. oui, car vous n'en parlez pas.
Exemple, on crée une route vers notre méthode somme du fichier ``somme.py``

Les APIs écrit avec ``hug`` peuvent être accédées depuis la ligne de commande, pour
cela, il suffit de rajouter ``@hug.cli()`` comme nous l'avons fait avec
``@hug.get()``.
.. code-block:: python3

.. quel rapport avec le routing?
"""Simple application effectuant une somme de deux nombres"""
import hug

@hug.get('/ajout')
def somme(val1:int, val2:int):
"""Retourne la somme des deux nombres passés en paramètre"""
return val1 + val2

Avant pour exécuter la méthode somme on entrait l'adresse suivante: http://localhost:8000/somme?val1=..&val2=..
Avec la route indiquée dans ``@hug.get()`` (/ajout) il suffit de remplace dans l'adresse précédente /somme par /ajout
http://localhost:8000/ajout?val1=..&val2=...

Suivant la taille du projet, l'ajout des routes avec la méthode get peut surcharger le code. Il existe donc une solution,
on peut avoir un fichier dans lequel nos méthodes sont déclarées et un second pour créer des routes.

Dans un autre fichier on va importer la méthode somme du fichier somme.py et créer une route

.. code-block:: python3

import hug
import somme

api = hug.API(__name__)
hug.get('/ajout')(somme.somme)

Le résultat est le même toujours en entrant cette url http://localhost:8000/ajout?val1=..&val2=..

Un avantage du routage est qu'il permet de bien nommer les urls.


Conclusion
==========

La bibliothèque hug_ offre un moyen très simplifié d'écrire des API REST.
La bibliothèque hug_ offre un moyen très simplifié d'écrire des APIs REST.
La syntaxe est assez claire, la documentation bien élaborée depuis le code, le
*versioning* est réalisé en une seule ligne de code.

Expand All @@ -386,3 +454,5 @@ Bibliographie
.. _hug: http://www.hug.rest/
.. _Flask: http://flask.pocoo.org/
.. _Django: https://www.djangoproject.com/
.. _annotations: http://sametmax.com/les-annotations-en-python-3/

2 changes: 2 additions & 0 deletions source/in
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ce fichier n'est pas nécessaire.

51 changes: 51 additions & 0 deletions source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,57 @@ Annexes
.. toctree::
:maxdepth: 1

builtins/index.rst
dunders/index.rst
super/index.rst
fstrings/index.rst
email/index.rst
abc/index.rst
collections/index.rst
csv/index.rst
hashlib/index.rst
io/index.rst
itertools/index.rst
json/index.rst
math/index.rst
multiprocessing/index.rst
re/index.rst
secrets/index.rst
statistics/index.rst
random/index.rst
unittest/index.rst

colorama/index.rst
hug/index.rst
pillow/index.rst
pygame/index.rst
pytest/index.rst
sphinx/index.rst
watchdog/index.rst

À propos de ce livre
====================

:Auteurs:
- Adrien Mendes <adrien.mendes@he-arc.ch>,
- André Neto Da Silva <andre.netodas@he-arc.ch>,
- Anthony Fleury <anth.fleury@gmail.com>,
- Axel Rieben <axel.rieben@he-arc.ch>
- Cédric Pahud <cedric.pahud@he-arc.ch>,
- Dany Chea <dany.chea@he-arc.ch>,
- Dylan Santos de Pinho <dylan.santosdeppinho@he-arc.ch>,
- Julien Feuillade <julien.feuillade@he-arc.ch>,
- Killian Castella <killian.castella@he-arc.ch>,
- Maël Pedretti <mael.pedretti@hotmail.fr>,
- Pedro Costa <pedro.costa@he-arc.ch>,
- Quentin Vaucher <quentin.vaucher@protonmail.com>,
- Sylvain Renaud <sylvain.renaud@he-arc.ch>,
- Guillaume Noguera <guillaume.noguera@he-arc.ch>,
- Yoan Blanc <yoan.blanc@he-arc.ch>
:Date: 2017-03-16
:Licence:
:ref:`licence`
=======
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avez-vous une bonne raison de toucher ce fichier-là?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

je corrigeais les conflits

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

si vous repartez depuis master, il n'y aura aucun conflit.

misc/about
misc/contrib
licence