From 9f3d73a0efe43eb4fb8bc646692837170d36fafb Mon Sep 17 00:00:00 2001 From: Ombang Ndo Charles Date: Thu, 16 Mar 2017 09:49:48 +0100 Subject: [PATCH 01/33] Initialisation du sujet API REST HUG --- source/hug/index.rst | 0 source/index.rst | 1 + 2 files changed, 1 insertion(+) create mode 100644 source/hug/index.rst diff --git a/source/hug/index.rst b/source/hug/index.rst new file mode 100644 index 00000000..e69de29b diff --git a/source/index.rst b/source/index.rst index 5e810f58..ff8e900b 100644 --- a/source/index.rst +++ b/source/index.rst @@ -31,6 +31,7 @@ Table des matières unittest/index.rst colorama/index.rst + hug/index.rst pillow/index.rst pygame/index.rst pytest/index.rst From fe59f4fd6a4577d840b9d1e077b7630399823dc6 Mon Sep 17 00:00:00 2001 From: Ombang Ndo Charles Date: Thu, 16 Mar 2017 11:04:03 +0100 Subject: [PATCH 02/33] Titre du document --- source/hug/index.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source/hug/index.rst b/source/hug/index.rst index e69de29b..e0f3c17c 100644 --- a/source/hug/index.rst +++ b/source/hug/index.rst @@ -0,0 +1,6 @@ +.. _hug-tutorial: + +API REST: HUG +============= + +Par Charles Ombang Ndo From 9b4737827e117ac010640c1955e30feca7dc657d Mon Sep 17 00:00:00 2001 From: Ombang Ndo Charles Date: Fri, 24 Mar 2017 21:13:53 +0100 Subject: [PATCH 03/33] Chapitre sur le HUG --- source/hug/index.rst | 295 ++++++++++++++++++++++++++++++++++++++++++- source/in | 2 + 2 files changed, 294 insertions(+), 3 deletions(-) create mode 100644 source/in diff --git a/source/hug/index.rst b/source/hug/index.rst index e0f3c17c..609e8bee 100644 --- a/source/hug/index.rst +++ b/source/hug/index.rst @@ -1,6 +1,295 @@ .. _hug-tutorial: -API REST: HUG -============= +``hug`` +======= -Par Charles Ombang Ndo +Par Charles Ombang Ndo [#contact]_ + +Introduction +------------ + +Une API (Application Programming Interface) est une façade regroupant des services qu'une application, offre à d'autres. Ces services sont définis sous forme de classes, de méthodes et généralement suivis d'une documentation décrivant le rôle de chaque composant de l'interface, exposant les utilisations 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(3), la librairie HUG est un outil assez puissant 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 +-------------------------- + +A l'origine REST (Representational State Transfer) est l'idée de définir un ensemble de règles qui mises ensemble, permettent de construire une API et décrivent la manière, donc la communication se passe entre le client et le serveur. Les dévéloppeurs n'ont plus à écrire leur propre méthode HTTP (GET, POST..) pour récupérer des données, c'est REST qui va définir de manière unique les méthodes à utiliser. La conséquence directe est que quelque soit la technologie employée côté serveur, les règles ne changeront pas, elles seront 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. + +Les formats d'échanges sont nombreux. Dans ce chapitre nous resterons sur du JSON. + +Pourquoi choisir HUG +-------------------- + +Les très célèbres frameworks que sont Flash 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 quelques lignes avec HUG. HUG supporte le versioning, il permet la documentation par le code et HUG intègre la validation des données. + +Installation de HUG +------------------- + +Les commandes HUG peuvent être installées en ligne de commande via la commande : ``pip3 install hug --upgrade``. + +Fonctionnement +-------------- + +Supposons une simple fonction permettant de faire la somme de deux nombres passés en paramètre. + +.. code-block:: python3 + + """Simple application effectuant une somme de deux nombres""" + + def somme(val1, val2): + """Retourne la somme des deux nombres passés en paramètre""" + return val1 + val2 + +Pour transformer cette fonction en une simple API, il suffit d'importer la librairie HUG et le tour est joué. Le code devient: + +.. code-block:: python3 + + """Simple application effectuant une somme de deux nombres""" + import hug + + @hug.get() + def somme(val1, val2): + """Retourne la somme des deux nombres passés en paramètre""" + return val1 + val2 + + +L'exécution du code ci-dessus via la commande $ hug -f hug.py (avec hug.py comme nom du fichier) lance le serveur sur le port 8000. En entrant l'adresse localhost:8000 on a une réponse au format JSON. Dans notre exemple on obtient: + +.. 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": "Simple API permettant la somme de deux nombres", + "handlers": { + "/somme": { + "GET": { + "usage": "La fonction retourne le résultat obtenu de la somme des deux nombres en param\u00e8tres", + "outputs": { + "format": "JSON (Javascript Serialized Object Notation)", + "content_type": "application/json" + }, + "inputs": { + "val1": { + "type": "Basic text / string value" + }, + "val2": { + "type": "Basic text / string value" + } + } + } + } + } + } + +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. + + +HUG et le versioning +--------------------- + +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 + + """Simple Exemple du versioning avec hug""" + import hug + + @hug.get('/echo', versions=1) + def echo(text): + return text + + + @hug.get('/echo', versions=range(2, 5)) + def echo(text): + 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. + +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: + +.. 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": "Simple Exemple du versioning avec hug", + "version": 4, + "versions": [ + 1, + 2, + 3, + 4 + ], + "handlers": { + "/echo": { + "GET": { + "outputs": { + "format": "JSON (Javascript Serialized Object Notation)", + "content_type": "application/json" + }, + "inputs": { + "text": { + "type": "Basic text / string value" + } + } + } + } + } + } + +Si on compare ce rendu JSON 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 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 +----------------------------- + +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 spécification est de clairement indiquer au niveau de la documentation le type de données attendues. + +.. code-block:: python3 + + """Test des types annotations""" + 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 aisément que l'argument text est de type int. Vérifions la sortie suivant 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", + "handlers": { + "/annota": { + "GET": { + "outputs": { + "format": "JSON (Javascript Serialized Object Notation)", + "content_type": "application/json" + }, + "inputs": { +                       "text": { +                           "type": "int(x=0) -> integer\nint(x, base=10) -> integer\n\nConvert a number or string to an integer, or return 0 if no arguments\nare given. If x is a number, return x.__int__(). For floating point\nnumbers, this truncates towards zero.\n\nIf x is not a number or if base is given, then x must be a string,\nbytes, or bytearray instance representing an integer literal in the\ngiven base. The literal can be preceded by '+' or '-' and be surrounded\nby whitespace. The base defaults to 10. Valid bases are 0 and 2-36.\nBase 0 means to interpret the base from the string as an integer literal.\n>>> int('0b100', base=0)\n4" +                       } + } + } + } + } + } + +On voit bien dans le bloc inputs la clé tpye, 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 une belle erreur comme celle ci-dessous: + +.. code-block:: json + {"errors": {"text": "invalid literal for int() with base 10: 'salut'"}} + +Il est important de noter que les annotations permettent implicitement de faire la validation automatique des données. + + + +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 possibilité de créer des directives personnalisées. + +.. code-block:: python3 + + import hug + + @hug.directive() + def salutation_general(greeting='hi', **kwargs): + return greeting + ' there!' + @hug.get() + def salut_anglais(greeting: salutation_general='hello'): + return greeting + @hug.get() + def salut_americain(greeting: salutation_general): + return greeting + + +Ci-dessus, on a créé une directive basée sur la fonction ``salutation_general(..)``. Cette fonction possède un paramètre avec une valeur par défaut. Si on va à l'adresse http://localhost:8000/salut_anglais on aura en retour ``hello there``, http://localhost:8000/salut_anglais retournera ``hi there``. En effet, dans la fonction ``salut_anglais(..)``, on passe la directive avec une nouvelle valeur par défaut qui est ``hello``. Cela a pour effet d'écraser la valeur par défaut ``hi``. Par contre la fonction ``salut_americain(..)`` prend en argument la même directive, mais aucune valeur n'est redéfinie, cela va conserver la valeur par défaut ``hi``. + +Utilisation des directives +-------------------------- + +Pour utiliser les directives dans nos fonctions, il existe deux méthodes. La première apparaît clairement, il s'agit de l'utilisation des types annotation ``greeting::directive``. On peut aussi utiliser le préfixe ``hug_``ce qui d'après notre exemple précédent deviendra avec la fonction ``salut_americain(...)`` : + +.. code-block:: python3 + + ...... + + @hug.get() + def salut_americain(hug_salutation_general='Yoo man'):. + ... +Il est aussi possible d'ajouter une valeur ``hug_salutation_general='Yoo man'``. + +Note: il est important d'ajouter **kwargs. + +Format de sortie +---------------- + +HUG utilise le JSON comme format par défaut. Heureusement, il offre la possibilité de définir des formats autres que JSON. Il existe différentes façons de spécifier le format que l'on veut utiliser + +.. code-block:: python3 + + hug.API(__name__).output_format = hug.output_format.html + + # Ou + + @hug.default_output_format() + def my_output_formatter(data, request, response): + # format personnalisé + + # Ou encore + + @hug.get(output=hug.output_format.html) + def my_endpoint(): + return # le code html généré + + + Il est possible de créer des formats de sortie personnalisés. Cela se passe comme le montre le code ci-dessous + +.. code-block:: python3 + + @hug.format.content_type('file/text') + def format_as_text(data, request=None, response=None): + return str(content).encode('utf8') + + +Le Routing +---------- + +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. le lien suivant http://www.hug.rest/website/learn/routing détaille la notion de Routing de façon plus élaborée et plus large. + +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()``. + + +Conclusion +---------- +     +La librairie HUG offre un moyen très simplifié d'écrire des API. La syntaxe est assez claire, la documentation bien élaborée depuis le code, le versioning est réalisé en une seule ligne de code. + + +Bibliographie +-------------- + +http://toilal.github.io/talk-python3-hug/#/hug-directives et http://www.hug.rest/website/learn/routing + + + + +.. [#contact] + \ No newline at end of file diff --git a/source/in b/source/in new file mode 100644 index 00000000..139597f9 --- /dev/null +++ b/source/in @@ -0,0 +1,2 @@ + + From 05eea0e78412af8512577e58b9edd597d902e986 Mon Sep 17 00:00:00 2001 From: Ombang Ndo Charles Date: Sat, 25 Mar 2017 08:17:35 +0100 Subject: [PATCH 04/33] espace --- source/hug/index.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/source/hug/index.rst b/source/hug/index.rst index 609e8bee..4eadb372 100644 --- a/source/hug/index.rst +++ b/source/hug/index.rst @@ -194,6 +194,7 @@ On voit bien dans le bloc inputs la clé tpye, on peut clairement voir que l'ent 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 + {"errors": {"text": "invalid literal for int() with base 10: 'salut'"}} Il est important de noter que les annotations permettent implicitement de faire la validation automatique des données. From 4acb8119b27ff6b23cd79f69e142eafb315e23f0 Mon Sep 17 00:00:00 2001 From: Ombang Ndo Charles Date: Sat, 25 Mar 2017 08:38:02 +0100 Subject: [PATCH 05/33] grr --- source/hug/index.rst | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/source/hug/index.rst b/source/hug/index.rst index 4eadb372..63f37d59 100644 --- a/source/hug/index.rst +++ b/source/hug/index.rst @@ -6,7 +6,7 @@ Par Charles Ombang Ndo [#contact]_ Introduction ------------- +============ Une API (Application Programming Interface) est une façade regroupant des services qu'une application, offre à d'autres. Ces services sont définis sous forme de classes, de méthodes et généralement suivis d'une documentation décrivant le rôle de chaque composant de l'interface, exposant les utilisations possibles et les normes d'utilisation. La plupart des applications actuelles offrent ces 'web services' plus connues sous RESTful web service. @@ -28,12 +28,12 @@ Pourquoi choisir HUG Les très célèbres frameworks que sont Flash 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 quelques lignes avec HUG. HUG supporte le versioning, il permet la documentation par le code et HUG intègre la validation des données. Installation de HUG -------------------- +=================== Les commandes HUG peuvent être installées en ligne de commande via la commande : ``pip3 install hug --upgrade``. Fonctionnement --------------- +============== Supposons une simple fonction permettant de faire la somme de deux nombres passés en paramètre. @@ -93,7 +93,7 @@ Maintenant pour voir le résultat de notre (petite) API, il suffit d'entrer dans HUG et le versioning ---------------------- +==================== 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. @@ -151,7 +151,7 @@ Si on compare ce rendu JSON au précédent, on remarque la présence du champ `v Type annotation et validation ------------------------------ +============================= 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 spécification est de clairement indiquer au niveau de la documentation le type de données attendues. @@ -202,7 +202,7 @@ Il est important de noter que les annotations permettent implicitement de faire 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 possibilité de créer des directives personnalisées. @@ -224,7 +224,7 @@ Les directives sont globalement des arguments enregistrés pour fournir automati Ci-dessus, on a créé une directive basée sur la fonction ``salutation_general(..)``. Cette fonction possède un paramètre avec une valeur par défaut. Si on va à l'adresse http://localhost:8000/salut_anglais on aura en retour ``hello there``, http://localhost:8000/salut_anglais retournera ``hi there``. En effet, dans la fonction ``salut_anglais(..)``, on passe la directive avec une nouvelle valeur par défaut qui est ``hello``. Cela a pour effet d'écraser la valeur par défaut ``hi``. Par contre la fonction ``salut_americain(..)`` prend en argument la même directive, mais aucune valeur n'est redéfinie, cela va conserver la valeur par défaut ``hi``. Utilisation des directives --------------------------- +========================== Pour utiliser les directives dans nos fonctions, il existe deux méthodes. La première apparaît clairement, il s'agit de l'utilisation des types annotation ``greeting::directive``. On peut aussi utiliser le préfixe ``hug_``ce qui d'après notre exemple précédent deviendra avec la fonction ``salut_americain(...)`` : @@ -233,14 +233,16 @@ Pour utiliser les directives dans nos fonctions, il existe deux méthodes. La pr ...... @hug.get() - def salut_americain(hug_salutation_general='Yoo man'):. + def salut_americain(hug_salutation_general='Yoo man'): ... + + Il est aussi possible d'ajouter une valeur ``hug_salutation_general='Yoo man'``. Note: il est important d'ajouter **kwargs. Format de sortie ----------------- +================ HUG utilise le JSON comme format par défaut. Heureusement, il offre la possibilité de définir des formats autres que JSON. Il existe différentes façons de spécifier le format que l'on veut utiliser @@ -279,13 +281,13 @@ Les APIs écrit avec HUG peuvent être accédées depuis la ligne de commande, p Conclusion ----------- +==========     La librairie HUG offre un moyen très simplifié d'écrire des API. La syntaxe est assez claire, la documentation bien élaborée depuis le code, le versioning est réalisé en une seule ligne de code. Bibliographie --------------- +------------- http://toilal.github.io/talk-python3-hug/#/hug-directives et http://www.hug.rest/website/learn/routing From 1ac764b303e5691ebae478ef715805ec5d0160e1 Mon Sep 17 00:00:00 2001 From: Ombang Ndo Charles Date: Sat, 25 Mar 2017 08:46:00 +0100 Subject: [PATCH 06/33] **kwargs --- source/hug/index.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/hug/index.rst b/source/hug/index.rst index 63f37d59..36f79323 100644 --- a/source/hug/index.rst +++ b/source/hug/index.rst @@ -239,7 +239,7 @@ Pour utiliser les directives dans nos fonctions, il existe deux méthodes. La pr Il est aussi possible d'ajouter une valeur ``hug_salutation_general='Yoo man'``. -Note: il est important d'ajouter **kwargs. +Note: il est important d'ajouter ``**kwargs``. Format de sortie ================ @@ -263,7 +263,7 @@ HUG utilise le JSON comme format par défaut. Heureusement, il offre la possibil return # le code html généré - Il est possible de créer des formats de sortie personnalisés. Cela se passe comme le montre le code ci-dessous +Il est possible de créer des formats de sortie personnalisés. Cela se passe comme le montre le code ci-dessous .. code-block:: python3 From ef8b42cb69895fd3cb74e2784ff787b125de45e1 Mon Sep 17 00:00:00 2001 From: Ombang Ndo Charles Date: Sat, 25 Mar 2017 09:16:33 +0100 Subject: [PATCH 07/33] suppression --- source/hug/index.rst | 31 ++++--------------------------- 1 file changed, 4 insertions(+), 27 deletions(-) diff --git a/source/hug/index.rst b/source/hug/index.rst index 36f79323..92e5b3ec 100644 --- a/source/hug/index.rst +++ b/source/hug/index.rst @@ -86,6 +86,7 @@ L'exécution du code ci-dessus via la commande $ hug -f hug.py (avec hug.py comm } } } + } 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. @@ -145,6 +146,7 @@ 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 `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 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`. @@ -164,32 +166,7 @@ Il est possible d'ajouter des fonctions aux paramètres de nos méthodes, pour e 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 aisément que l'argument text est de type int. Vérifions la sortie suivant 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", - "handlers": { - "/annota": { - "GET": { - "outputs": { - "format": "JSON (Javascript Serialized Object Notation)", - "content_type": "application/json" - }, - "inputs": { -                       "text": { -                           "type": "int(x=0) -> integer\nint(x, base=10) -> integer\n\nConvert a number or string to an integer, or return 0 if no arguments\nare given. If x is a number, return x.__int__(). For floating point\nnumbers, this truncates towards zero.\n\nIf x is not a number or if base is given, then x must be a string,\nbytes, or bytearray instance representing an integer literal in the\ngiven base. The literal can be preceded by '+' or '-' and be surrounded\nby whitespace. The base defaults to 10. Valid bases are 0 and 2-36.\nBase 0 means to interpret the base from the string as an integer literal.\n>>> int('0b100', base=0)\n4" -                       } - } - } - } - } - } - -On voit bien dans le bloc inputs la clé tpye, on peut clairement voir que l'entrée est de type int. +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 aisément que l'argument text est de type int. En vérifier via l'adresse http://localhost:8000 , on voit bien dans le bloc inputs la clé type, qui explique clairement le type de données attendu en entrée. Ici un int. Si on entre l'adresse http://localhost:8000/annota?text=salut on a en retour une belle erreur comme celle ci-dessous: @@ -239,7 +216,7 @@ Pour utiliser les directives dans nos fonctions, il existe deux méthodes. La pr Il est aussi possible d'ajouter une valeur ``hug_salutation_general='Yoo man'``. -Note: il est important d'ajouter ``**kwargs``. +Note: il est important d'ajouter ``**kwargs`. Format de sortie ================ From 078dd624dac87a48fa9bfa3add50188be6162419 Mon Sep 17 00:00:00 2001 From: OmbicheFlag Date: Wed, 14 Jun 2017 15:26:20 +0200 Subject: [PATCH 08/33] modif --- source/hug/index.rst | 363 +++++++++++++++++++++++++++++-------------- 1 file changed, 244 insertions(+), 119 deletions(-) diff --git a/source/hug/index.rst b/source/hug/index.rst index 92e5b3ec..1ec591b1 100644 --- a/source/hug/index.rst +++ b/source/hug/index.rst @@ -1,36 +1,69 @@ .. _hug-tutorial: -``hug`` +======= +``hug_`` ======= -Par Charles Ombang Ndo [#contact]_ +Par Charles Ombang Ndo [#co]_ Introduction ============ -Une API (Application Programming Interface) est une façade regroupant des services qu'une application, offre à d'autres. Ces services sont définis sous forme de classes, de méthodes et généralement suivis d'une documentation décrivant le rôle de chaque composant de l'interface, exposant les utilisations possibles et les normes d'utilisation. La plupart des applications actuelles offrent ces 'web services' plus connues sous RESTful web service. +Une API (Application Programming Interface) est une façade regroupant des +services qu'une application, offre à d'autres. Ces services sont définis sous +forme de classes, de méthodes et généralement suivis d'une documentation +décrivant le rôle de chaque composant de l'interface, exposant les utilisations +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 +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_`` +------------------------------ + +A l'origine REST (Representational State Transfer) est l'idée de définir un +ensemble de règles qui mises ensemble, permettent de construire une API et +décrivent la manière, donc la communication se passe entre le client et le +serveur. Les dévéloppeurs n'ont plus à écrire leur propre méthode HTTP (GET, +POST..) pour récupérer des données, c'est REST qui va définir de manière unique +les méthodes à utiliser. La conséquence directe est que quelque soit la +technologie employée côté serveur, les règles ne changeront pas, elles seront +tout le temps les mêmes. -Dans l'univers Python(3), la librairie HUG est un outil assez puissant 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é. +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: -RESTful web service et HUG --------------------------- +- GET: récupération de données, +- POST: ajout de données +- PUT: modifications de données +- DELETE: suppression de données. -A l'origine REST (Representational State Transfer) est l'idée de définir un ensemble de règles qui mises ensemble, permettent de construire une API et décrivent la manière, donc la communication se passe entre le client et le serveur. Les dévéloppeurs n'ont plus à écrire leur propre méthode HTTP (GET, POST..) pour récupérer des données, c'est REST qui va définir de manière unique les méthodes à utiliser. La conséquence directe est que quelque soit la technologie employée côté serveur, les règles ne changeront pas, elles seront tout le temps les mêmes. +Les formats d'échanges sont nombreux. Dans ce chapitre, nous resterons sur du +:ref:`JSON `. -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. +Pourquoi choisir ``hug_`` +------------------------ -Les formats d'échanges sont nombreux. Dans ce chapitre nous resterons sur du JSON. +Les très célèbres frameworks que sont Flask_ et Django_ sont bousculés par les +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 il intègre la validation des données. -Pourquoi choisir HUG --------------------- +Avant de commencer +------------------ -Les très célèbres frameworks que sont Flash 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 quelques lignes avec HUG. HUG supporte le versioning, il permet la documentation par le code et HUG intègre la validation des données. +Pour utiliser la bibliothèque, il faut au préalable l'installer pour ce faire, on utilise la commande +``pip`` comme suit: -Installation de HUG -=================== +.. code-block:: console + + $ pip3 install hug -U -Les commandes HUG peuvent être installées en ligne de commande via la commande : ``pip3 install hug --upgrade``. Fonctionnement ============== @@ -40,67 +73,76 @@ Supposons une simple fonction permettant de faire la somme de deux nombres pass .. code-block:: python3 """Simple application effectuant une somme de deux nombres""" - + def somme(val1, val2): - """Retourne la somme des deux nombres passés en paramètre""" - return val1 + val2 - -Pour transformer cette fonction en une simple API, il suffit d'importer la librairie HUG et le tour est joué. Le code devient: + """Retourne la somme des deux nombres passés en paramètre""" + return val1 + val2 + +Pour transformer cette fonction en une simple API, il suffit d'importer la +bibliothèque hug_ et le tour est joué. Le code du fichier ``somme.py``. .. code-block:: python3 """Simple application effectuant une somme de deux nombres""" import hug - + @hug.get() def somme(val1, val2): """Retourne la somme des deux nombres passés en paramètre""" return val1 + val2 - -L'exécution du code ci-dessus via la commande $ hug -f hug.py (avec hug.py comme nom du fichier) lance le serveur sur le port 8000. En entrant l'adresse localhost:8000 on a une réponse au format JSON. Dans notre exemple on obtient: - + +L'exécution du code ci-dessus via la commande. + +.. code-block:: console + + $ 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 :ref:`JSON `. Dans notre exemple +on obtient: + .. 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": { + "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": "Simple API permettant la somme de deux nombres", - "handlers": { - "/somme": { - "GET": { - "usage": "La fonction retourne le résultat obtenu de la somme des deux nombres en param\u00e8tres", - "outputs": { - "format": "JSON (Javascript Serialized Object Notation)", - "content_type": "application/json" - }, - "inputs": { - "val1": { - "type": "Basic text / string value" + "handlers": { + "/somme": { + "GET": { + "usage": "La fonction retourne le résultat obtenu de la somme des deux nombres en param\u00e8tres", + "outputs": { + "format": "JSON (Javascript Serialized Object Notation)", + "content_type": "application/json" }, - "val2": { - "type": "Basic text / string value" + "inputs": { + "val1": { + "type": "Basic text / string value" + }, + "val2": { + "type": "Basic text / string value" + } } } } } } } - } -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. +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 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= .. il suffit de passer les valeurs aux paramètres. -HUG et le versioning +hug_ et le versioning ==================== -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 - + """Simple Exemple du versioning avec hug""" import hug @@ -112,50 +154,62 @@ Comme souligné auparavant, HUG supporte et gère très bien le versioning. On p @hug.get('/echo', versions=range(2, 5)) def echo(text): 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: .. 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": "Simple Exemple du versioning avec hug", - "version": 4, - "versions": [ - 1, - 2, - 3, - 4 - ], - "handlers": { - "/echo": { - "GET": { - "outputs": { - "format": "JSON (Javascript Serialized Object Notation)", - "content_type": "application/json" - }, - "inputs": { - "text": { - "type": "Basic text / string value" + "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": "Simple Exemple du versioning avec hug", + "version": 4, + "versions": [ + 1, + 2, + 3, + 4 + ], + "handlers": { + "/echo": { + "GET": { + "outputs": { + "format": "JSON (Javascript Serialized Object Notation)", + "content_type": "application/json" + }, + "inputs": { + "text": { + "type": "Basic text / string value" + } } } } } } - } } - -Si on compare ce rendu JSON 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 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`. + +Si on compare ce rendu JSON 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 +. 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 spécification est de clairement indiquer au niveau de la documentation le type de données attendues. +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. Pour faire de la validation +des données, il suffit de faire suivre le pa``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. .. code-block:: python3 @@ -165,23 +219,61 @@ Il est possible d'ajouter des fonctions aux paramètres de nos méthodes, pour e @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 aisément que l'argument text est de type int. En vérifier via l'adresse http://localhost:8000 , on voit bien dans le bloc inputs la clé type, qui explique clairement le type de données attendu en entrée. Ici un int. -Si on entre l'adresse http://localhost:8000/annota?text=salut on a en retour une belle erreur comme celle ci-dessous: +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 +aisément que l'argument text est de type int. Vérifions la sortie suivant +l'adresse .. code-block:: json - {"errors": {"text": "invalid literal for int() with base 10: 'salut'"}} - -Il est important de noter que les annotations permettent implicitement de faire la validation automatique des données. - - - + { + "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", + "handlers": { + "/annota": { + "GET": { + "outputs": { + "format": "JSON (Javascript Serialized Object Notation)", + "content_type": "application/json" + }, + "inputs": { + "text": { + "type": "int(x=0) -> integer\nint(x, base=10) -> integer\n\nConvert a number or string to an integer, or return 0 if no arguments\nare given If x is a number, return x __int__() For floating point\nnumbers, this truncates towards zero \n\nIf x is not a number or if base is given, then x must be a string,\nbytes, or bytearray instance representing an integer literal in the\ngiven base The literal can be preceded by '+' or '-' and be surrounded\nby whitespace The base defaults to 10 Valid bases are 0 and 2-36 \nBase 0 means to interpret the base from the string as an integer literal \n>>> int('0b100', base=0)\n4" + } + } + } + } + } + } + } + +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 on a en retour +une belle erreur comme celle ci-dessous: + +.. code-block:: json + + { + "errors": { + "text": "invalid literal for int() with base 10: 'salut'" + } + } + +Il est important de noter que les annotations permettent implicitement de faire +la validation automatique des données. + + 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 possibilité de créer des directives personnalisées. +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 +possibilité de créer des directives personnalisées. .. code-block:: python3 @@ -196,80 +288,113 @@ Les directives sont globalement des arguments enregistrés pour fournir automati @hug.get() def salut_americain(greeting: salutation_general): return greeting - -Ci-dessus, on a créé une directive basée sur la fonction ``salutation_general(..)``. Cette fonction possède un paramètre avec une valeur par défaut. Si on va à l'adresse http://localhost:8000/salut_anglais on aura en retour ``hello there``, http://localhost:8000/salut_anglais retournera ``hi there``. En effet, dans la fonction ``salut_anglais(..)``, on passe la directive avec une nouvelle valeur par défaut qui est ``hello``. Cela a pour effet d'écraser la valeur par défaut ``hi``. Par contre la fonction ``salut_americain(..)`` prend en argument la même directive, mais aucune valeur n'est redéfinie, cela va conserver la valeur par défaut ``hi``. + +Ci-dessus, on a créé une directive basée sur la fonction +``salutation_general(..)``. Cette fonction possède un paramètre avec une valeur +par défaut. Si on va à l'adresse http://localhost:8000/salut_anglais on aura en +retour ``hello there``, http://localhost:8000/salut_anglais retournera ``hi +there``. En effet, dans la fonction ``salut_anglais(..)``, on passe la +directive avec une nouvelle valeur par défaut qui est ``hello``. Cela a pour +effet d'écraser la valeur par défaut ``hi``. Par contre la fonction +``salut_americain(..)`` prend en argument la même directive, mais aucune valeur +n'est redéfinie, cela va conserver la valeur par défaut ``hi``. Utilisation des directives ========================== -Pour utiliser les directives dans nos fonctions, il existe deux méthodes. La première apparaît clairement, il s'agit de l'utilisation des types annotation ``greeting::directive``. On peut aussi utiliser le préfixe ``hug_``ce qui d'après notre exemple précédent deviendra avec la fonction ``salut_americain(...)`` : +Pour utiliser les directives dans nos fonctions, il existe deux méthodes. La +première apparaît clairement, il s'agit de l'utilisation des types annotation +``greeting::directive``. On peut aussi utiliser le préfixe ``hug_`` ce qui +d'après notre exemple précédent deviendra avec la fonction +``salut_americain(...)`` : .. code-block:: python3 - ...... - - @hug.get() - def salut_americain(hug_salutation_general='Yoo man'): - ... + @hug.get() + def salut_americain(hug_salutation_general='Yoo man'): + pass Il est aussi possible d'ajouter une valeur ``hug_salutation_general='Yoo man'``. -Note: il est important d'ajouter ``**kwargs`. +.. note:: il est important d'ajouter ``**kwargs``. Format de sortie ================ -HUG utilise le JSON comme format par défaut. Heureusement, il offre la possibilité de définir des formats autres que JSON. Il existe différentes façons de spécifier le format que l'on veut utiliser +hug_ utilise le JSON comme format par défaut. Heureusement, il offre +la possibilité de définir des formats autres que JSON. Il existe différentes +façons de spécifier le format que l'on veut utiliser .. code-block:: python3 hug.API(__name__).output_format = hug.output_format.html - - # Ou - + + # Ou + @hug.default_output_format() def my_output_formatter(data, request, response): - # format personnalisé - + """Format personnalisé.""" + # Ou encore - + @hug.get(output=hug.output_format.html) def my_endpoint(): - return # le code html généré - - -Il est possible de créer des formats de sortie personnalisés. Cela se passe comme le montre le code ci-dessous - + """Retourne du HTML.""" + + +Il est possible de créer des formats de sortie personnalisés. Cela se passe +comme le montre le code ci-dessous + .. code-block:: python3 - + @hug.format.content_type('file/text') def format_as_text(data, request=None, response=None): - return str(content).encode('utf8') - - + return str(content).encode('utf-8') + + +.. warning:: + + le ``Content-Type`` nommé ``file/text`` n'existe pas. Ce n'est pas donc pas + un exemple utilisable en l'état. + + .. Yoan + Le Routing ---------- -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. le lien suivant http://www.hug.rest/website/learn/routing détaille la notion de Routing de façon plus élaborée et plus large. +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 +`_ détaille la notion de *Routing* +de façon plus élaborée et plus large. -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()``. +.. oui, car vous n'en parlez pas. +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()``. + +.. quel rapport avec le routing? Conclusion ========== -     -La librairie HUG offre un moyen très simplifié d'écrire des API. La syntaxe est assez claire, la documentation bien élaborée depuis le code, le versioning est réalisé en une seule ligne de code. + +La bibliothèque hug_ offre un moyen très simplifié d'écrire des API 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. Bibliographie ------------- -http://toilal.github.io/talk-python3-hug/#/hug-directives et http://www.hug.rest/website/learn/routing - +- Site de ``hug``: http://www.hug.rest/ +- *Réaliser une API avec Python 3*, par Rémi Alvergnat, http://toilal.github.io/talk-python3-hug/ +.. [#co] +.. liens externes. -.. [#contact] - \ No newline at end of file +.. _hug: http://www.hug.rest/ +.. _Flask: http://flask.pocoo.org/ +.. _Django: https://www.djangoproject.com/ From 4031aacc482c57d2ca7b982eca48cbd2344b3757 Mon Sep 17 00:00:00 2001 From: OmbicheFlag Date: Wed, 14 Jun 2017 17:01:58 +0200 Subject: [PATCH 09/33] Create index.rst --- source/hug/index.rst | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/source/hug/index.rst b/source/hug/index.rst index 1ec591b1..6d477ae0 100644 --- a/source/hug/index.rst +++ b/source/hug/index.rst @@ -21,7 +21,7 @@ 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_`` +RESTful web service et ``hug`` ------------------------------ A l'origine REST (Representational State Transfer) est l'idée de définir un @@ -45,7 +45,7 @@ méthodes du protocole HTTP, ce sont les verbes: Les formats d'échanges sont nombreux. Dans ce chapitre, nous resterons sur du :ref:`JSON `. -Pourquoi choisir ``hug_`` +Pourquoi choisir ``hug`` ------------------------ Les très célèbres frameworks que sont Flask_ et Django_ sont bousculés par les @@ -135,7 +135,7 @@ On peut remarquer que la documentation est très claire, la clé overview nous r 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. -hug_ et le versioning +hug et le versioning ==================== 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. @@ -206,31 +206,31 @@ 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. Pour faire de la validation -des données, il suffit de faire suivre le pa``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. .. 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 +l'adresse . .. 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": { @@ -263,8 +263,8 @@ 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 From c443da1178b20278b4f474b71cc6978ba14cc546 Mon Sep 17 00:00:00 2001 From: OmbicheFlag Date: Wed, 14 Jun 2017 17:04:04 +0200 Subject: [PATCH 10/33] Create index.rst --- source/hug/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/hug/index.rst b/source/hug/index.rst index 6d477ae0..209c6cfe 100644 --- a/source/hug/index.rst +++ b/source/hug/index.rst @@ -1,7 +1,7 @@ .. _hug-tutorial: ======= -``hug_`` +``hug`` ======= Par Charles Ombang Ndo [#co]_ From 7d7860ef18fdd4b20ffb792adf5680c6b4a4ce0d Mon Sep 17 00:00:00 2001 From: OmbicheFlag Date: Wed, 14 Jun 2017 17:31:56 +0200 Subject: [PATCH 11/33] Create index.rst --- source/hug/index.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/source/hug/index.rst b/source/hug/index.rst index 209c6cfe..a8b01920 100644 --- a/source/hug/index.rst +++ b/source/hug/index.rst @@ -1,5 +1,6 @@ .. _hug-tutorial: + ======= ``hug`` ======= From 8801f14e2cb72a04bef979fd3948643f93e27d01 Mon Sep 17 00:00:00 2001 From: OmbicheFlag Date: Wed, 14 Jun 2017 17:33:10 +0200 Subject: [PATCH 12/33] Add files via upload --- source/hug/hug.png | Bin 0 -> 23195 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 source/hug/hug.png diff --git a/source/hug/hug.png b/source/hug/hug.png new file mode 100644 index 0000000000000000000000000000000000000000..f4bb7b1153e39d468a13fbb2da188abe90de7ca6 GIT binary patch literal 23195 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 Date: Wed, 14 Jun 2017 17:35:40 +0200 Subject: [PATCH 13/33] logo logo de la biblio --- source/hug/index.rst | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/source/hug/index.rst b/source/hug/index.rst index a8b01920..c5cfd9ea 100644 --- a/source/hug/index.rst +++ b/source/hug/index.rst @@ -1,6 +1,10 @@ .. _hug-tutorial: - +.. image:: hug.png + :scale: 50% + :align: right + :alt: hug + ======= ``hug`` ======= From 2073627bb26c220ba70184cae96de9697733daac Mon Sep 17 00:00:00 2001 From: OmbicheFlag Date: Wed, 14 Jun 2017 17:42:17 +0200 Subject: [PATCH 14/33] Create index.rst --- source/hug/index.rst | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/source/hug/index.rst b/source/hug/index.rst index c5cfd9ea..363bc9c4 100644 --- a/source/hug/index.rst +++ b/source/hug/index.rst @@ -1,14 +1,16 @@ .. _hug-tutorial: -.. image:: hug.png - :scale: 50% - :align: right - :alt: hug - + ======= ``hug`` ======= + +.. image:: hug.png + :scale: 50% + :alt: hug + + Par Charles Ombang Ndo [#co]_ Introduction From e7a26398f9bbee73e1d804840d6832835c08a84f Mon Sep 17 00:00:00 2001 From: OmbicheFlag Date: Wed, 14 Jun 2017 17:58:11 +0200 Subject: [PATCH 15/33] Terme annotation --- source/hug/index.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/source/hug/index.rst b/source/hug/index.rst index 363bc9c4..2359edc9 100644 --- a/source/hug/index.rst +++ b/source/hug/index.rst @@ -24,7 +24,7 @@ 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é. @@ -216,7 +216,7 @@ 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. 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 annotation_ en python .. code-block:: python3 @@ -227,7 +227,7 @@ de données attendues. def annota(text:int): return text -Le code ci-dessus montre comment valider les données automatiquement. l'argument de la +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 . @@ -405,3 +405,4 @@ Bibliographie .. _hug: http://www.hug.rest/ .. _Flask: http://flask.pocoo.org/ .. _Django: https://www.djangoproject.com/ +.. _Annotation: http://sametmax.com/les-annotations-en-python-3/ From 5c47eba1d0540dac89692f6903fca5bfddabce89 Mon Sep 17 00:00:00 2001 From: OmbicheFlag Date: Wed, 14 Jun 2017 18:01:24 +0200 Subject: [PATCH 16/33] Update index.rst --- source/hug/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/hug/index.rst b/source/hug/index.rst index 2359edc9..a00d235c 100644 --- a/source/hug/index.rst +++ b/source/hug/index.rst @@ -216,7 +216,7 @@ 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. 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. Ceci est connu sous le terme annotation_ en python +de données attendues. Ceci est connu sous le terme annotations_ en python .. code-block:: python3 From ee08666d4fc2d6bad97d2c41d3b349d15d5b14d9 Mon Sep 17 00:00:00 2001 From: OmbicheFlag Date: Wed, 14 Jun 2017 18:09:53 +0200 Subject: [PATCH 17/33] Create index.rst --- source/hug/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/hug/index.rst b/source/hug/index.rst index a00d235c..4f549175 100644 --- a/source/hug/index.rst +++ b/source/hug/index.rst @@ -402,7 +402,7 @@ Bibliographie .. liens externes. -.. _hug: http://www.hug.rest/ +_hug: .. _Flask: http://flask.pocoo.org/ .. _Django: https://www.djangoproject.com/ .. _Annotation: http://sametmax.com/les-annotations-en-python-3/ From 9a4afc6b33b49215796f14f7a9739cccb5c1f30c Mon Sep 17 00:00:00 2001 From: OmbicheFlag Date: Wed, 14 Jun 2017 18:11:12 +0200 Subject: [PATCH 18/33] Create index.rst --- source/hug/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/hug/index.rst b/source/hug/index.rst index 4f549175..d7f50741 100644 --- a/source/hug/index.rst +++ b/source/hug/index.rst @@ -402,7 +402,7 @@ Bibliographie .. liens externes. -_hug: +.. _hug: .. _Flask: http://flask.pocoo.org/ .. _Django: https://www.djangoproject.com/ .. _Annotation: http://sametmax.com/les-annotations-en-python-3/ From 815bc5b4fa7aaf98ff2e6bbda1740d817f8df1cf Mon Sep 17 00:00:00 2001 From: OmbicheFlag Date: Wed, 14 Jun 2017 18:13:44 +0200 Subject: [PATCH 19/33] Create index.rst --- source/hug/index.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/hug/index.rst b/source/hug/index.rst index d7f50741..4e549fad 100644 --- a/source/hug/index.rst +++ b/source/hug/index.rst @@ -402,7 +402,7 @@ Bibliographie .. liens externes. -.. _hug: +.. _hug: http://www.hug.rest/ .. _Flask: http://flask.pocoo.org/ .. _Django: https://www.djangoproject.com/ -.. _Annotation: http://sametmax.com/les-annotations-en-python-3/ +.. _annotations: http://sametmax.com/les-annotations-en-python-3/ From 519506a2eea101747953ad3ad3a82100efed7d06 Mon Sep 17 00:00:00 2001 From: OmbicheFlag Date: Wed, 14 Jun 2017 18:35:54 +0200 Subject: [PATCH 20/33] Create index.rst --- source/hug/index.rst | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/source/hug/index.rst b/source/hug/index.rst index 4e549fad..c4cea74d 100644 --- a/source/hug/index.rst +++ b/source/hug/index.rst @@ -139,8 +139,12 @@ 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 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= .. il suffit de passer les valeurs aux paramètres. +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 ==================== @@ -216,7 +220,7 @@ 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. 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. Ceci est connu sous le terme annotations_ en python +de données attendues. Ceci est connu sous le terme annotations_ en python. .. code-block:: python3 @@ -366,8 +370,6 @@ comme le montre le code ci-dessous le ``Content-Type`` nommé ``file/text`` n'existe pas. Ce n'est pas donc pas un exemple utilisable en l'état. - .. Yoan - Le Routing ---------- @@ -378,12 +380,6 @@ de façon plus élaborée et plus large. .. oui, car vous n'en parlez pas. -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()``. - -.. quel rapport avec le routing? - Conclusion ========== @@ -391,6 +387,9 @@ La bibliothèque hug_ offre un moyen très simplifié d'écrire des API 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. +:file:`test.txt` + + Bibliographie ------------- From a35db90d87a0c07771b35e267c28ccdeba2403e1 Mon Sep 17 00:00:00 2001 From: OmbicheFlag Date: Wed, 14 Jun 2017 18:37:57 +0200 Subject: [PATCH 21/33] Create somme.py --- source/hug/somme.py | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 source/hug/somme.py diff --git a/source/hug/somme.py b/source/hug/somme.py new file mode 100644 index 00000000..bb7ba8ad --- /dev/null +++ b/source/hug/somme.py @@ -0,0 +1,7 @@ +"""Simple application effectuant une somme de deux nombres""" +import hug + +@hug.get() +def somme(val1, val2): + """Retourne la somme des deux nombres passés en paramètre""" + return val1 + val2 From cb452f28b4227768aa922600a46d7344596a2b84 Mon Sep 17 00:00:00 2001 From: OmbicheFlag Date: Wed, 14 Jun 2017 18:38:29 +0200 Subject: [PATCH 22/33] Create index.rst --- source/hug/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/hug/index.rst b/source/hug/index.rst index c4cea74d..c65a43d0 100644 --- a/source/hug/index.rst +++ b/source/hug/index.rst @@ -387,7 +387,7 @@ La bibliothèque hug_ offre un moyen très simplifié d'écrire des API 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. -:file:`test.txt` +:file:`somme.py` From cf44feace1b8dd1631f5d0f4f0e2a74e9b72da56 Mon Sep 17 00:00:00 2001 From: OmbicheFlag Date: Wed, 14 Jun 2017 20:23:59 +0200 Subject: [PATCH 23/33] Create index.rst --- source/hug/index.rst | 44 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/source/hug/index.rst b/source/hug/index.rst index c65a43d0..d71206bd 100644 --- a/source/hug/index.rst +++ b/source/hug/index.rst @@ -10,7 +10,6 @@ :scale: 50% :alt: hug - Par Charles Ombang Ndo [#co]_ Introduction @@ -370,15 +369,45 @@ comme le montre le code ci-dessous le ``Content-Type`` nommé ``file/text`` n'existe pas. Ce n'est pas donc pas un exemple utilisable en l'état. -Le Routing +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 -`_ 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_. + +Exemple, on crée une route vers notre méthode somme du fichier ``somme.py`` + +.. code-block:: python3 + + """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 -.. oui, car vous n'en parlez pas. +Avant pour exécuter la méthode somme on entrait l'adresse suivante: +Avec la route indiquée dans ``@hug.get()`` (/ajout) il suffit de remplace dans l'adresse précédente /somme par /ajout +. + +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 + + Un avantage du routage est qu'il permet de bien nommer les urls. Conclusion ========== @@ -387,9 +416,6 @@ La bibliothèque hug_ offre un moyen très simplifié d'écrire des API 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. -:file:`somme.py` - - Bibliographie ------------- From 9df5b23ed12f63f35468c16470d290617a6e7c98 Mon Sep 17 00:00:00 2001 From: OmbicheFlag Date: Wed, 14 Jun 2017 20:35:46 +0200 Subject: [PATCH 24/33] Create index.rst --- source/hug/index.rst | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/source/hug/index.rst b/source/hug/index.rst index d71206bd..1aebfabc 100644 --- a/source/hug/index.rst +++ b/source/hug/index.rst @@ -10,6 +10,7 @@ :scale: 50% :alt: hug + Par Charles Ombang Ndo [#co]_ Introduction @@ -43,10 +44,10 @@ 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 `. @@ -388,9 +389,9 @@ Exemple, on crée une route vers notre méthode somme du fichier ``somme.py`` """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: +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. @@ -405,14 +406,14 @@ Dans un autre fichier on va importer la méthode somme du fichier somme.py et cr api = hug.API(__name__) hug.get('/ajout')(somme.somme) - Le résultat est le même toujours en entrant cette url + 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. From ff9540cc9b6dd187a2dd34955301152119482f08 Mon Sep 17 00:00:00 2001 From: OmbicheFlag Date: Wed, 14 Jun 2017 20:41:53 +0200 Subject: [PATCH 25/33] Create index.rst --- source/hug/index.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/hug/index.rst b/source/hug/index.rst index 1aebfabc..69715e72 100644 --- a/source/hug/index.rst +++ b/source/hug/index.rst @@ -137,7 +137,7 @@ 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 de l'API, leurs types et le format de retour. +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 ` 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. @@ -202,11 +202,11 @@ 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 ` 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 -. 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 @@ -263,7 +263,7 @@ l'adresse . 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 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 From 8bdb9cf5a067ba9d4f8c9da8aa49ccb397e1a82b Mon Sep 17 00:00:00 2001 From: OmbicheFlag Date: Wed, 14 Jun 2017 21:17:04 +0200 Subject: [PATCH 26/33] Create index.rst --- source/hug/index.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/hug/index.rst b/source/hug/index.rst index 69715e72..6a8b00d8 100644 --- a/source/hug/index.rst +++ b/source/hug/index.rst @@ -8,8 +8,9 @@ .. image:: hug.png :scale: 50% + :align: center :alt: hug - + Par Charles Ombang Ndo [#co]_ From 705de2fd6c66cc4ba2ac991ac1f37fc8d9f8ab3b Mon Sep 17 00:00:00 2001 From: OmbicheFlag Date: Wed, 14 Jun 2017 21:46:17 +0200 Subject: [PATCH 27/33] Update somme.py --- source/hug/somme.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/hug/somme.py b/source/hug/somme.py index bb7ba8ad..994a4437 100644 --- a/source/hug/somme.py +++ b/source/hug/somme.py @@ -3,5 +3,6 @@ @hug.get() def somme(val1, val2): - """Retourne la somme des deux nombres passés en paramètre""" - return val1 + val2 + + """Retourne la somme des deux nombres passés en paramètre""" + return val1 + val2 From fa05fa5f69242f7afca5e9b34343052dc8da26a9 Mon Sep 17 00:00:00 2001 From: OmbicheFlag Date: Wed, 14 Jun 2017 21:54:10 +0200 Subject: [PATCH 28/33] Update somme.py --- source/hug/somme.py | 1 - 1 file changed, 1 deletion(-) diff --git a/source/hug/somme.py b/source/hug/somme.py index 994a4437..824e2793 100644 --- a/source/hug/somme.py +++ b/source/hug/somme.py @@ -3,6 +3,5 @@ @hug.get() def somme(val1, val2): - """Retourne la somme des deux nombres passés en paramètre""" return val1 + val2 From 9b2899ba12d6b847a8820188869e75f529c30b7c Mon Sep 17 00:00:00 2001 From: OmbicheFlag Date: Wed, 14 Jun 2017 22:01:55 +0200 Subject: [PATCH 29/33] Delete somme.py --- source/hug/somme.py | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 source/hug/somme.py diff --git a/source/hug/somme.py b/source/hug/somme.py deleted file mode 100644 index 824e2793..00000000 --- a/source/hug/somme.py +++ /dev/null @@ -1,7 +0,0 @@ -"""Simple application effectuant une somme de deux nombres""" -import hug - -@hug.get() -def somme(val1, val2): - """Retourne la somme des deux nombres passés en paramètre""" - return val1 + val2 From a21c778c376c5a16e67a1b0671ca8d352b700710 Mon Sep 17 00:00:00 2001 From: OmbicheFlag Date: Wed, 14 Jun 2017 23:13:56 +0200 Subject: [PATCH 30/33] content-type Quelques mot sur les format de sortie --- source/hug/index.rst | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/source/hug/index.rst b/source/hug/index.rst index 774aa73c..53d12d56 100644 --- a/source/hug/index.rst +++ b/source/hug/index.rst @@ -64,17 +64,6 @@ 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 il intègre la validation des données. -Avant de commencer ------------------- - -Pour utiliser la bibliothèque, il faut au préalable l'installer pour ce faire, on utilise la commande -``pip`` comme suit: - -.. code-block:: console - - $ pip3 install hug -U - - Fonctionnement ============== @@ -378,16 +367,30 @@ 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') + +Le format par défaut est le :ref:`JSON `. L'une des technique pour définir un nouveau format par défaut est +``hug.API(__name__).http.output_format = hug.`` 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. +.. code-block:: python3 + + """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 "

{}

".format(val1 + val2) + + +donc il suffit de spécifier le format dans le get ``@hug.get(output = hug.output = hug.)``. Le routage ---------- From 44f5f54c31cf7cf69c64bc5a82b9991d4aca509a Mon Sep 17 00:00:00 2001 From: OmbicheFlag Date: Wed, 14 Jun 2017 23:58:19 +0200 Subject: [PATCH 31/33] Create index.rst --- source/hug/index.rst | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/source/hug/index.rst b/source/hug/index.rst index 53d12d56..db758bad 100644 --- a/source/hug/index.rst +++ b/source/hug/index.rst @@ -139,9 +139,7 @@ Maintenant pour voir le résultat de notre (petite) API, il suffit d'entrer dans ``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()``. - +cela, il suffit de rajouter ``@hug.cli()`` comme nous l'avons fait avec``@hug.get()``. hug et le versioning ==================== From d9b95dd5908a6f9e7e52abd9652193f80b6b230f Mon Sep 17 00:00:00 2001 From: OmbicheFlag Date: Thu, 15 Jun 2017 00:07:08 +0200 Subject: [PATCH 32/33] Create index.rst --- source/hug/index.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/hug/index.rst b/source/hug/index.rst index db758bad..87adfee9 100644 --- a/source/hug/index.rst +++ b/source/hug/index.rst @@ -139,7 +139,8 @@ Maintenant pour voir le résultat de notre (petite) API, il suffit d'entrer dans ``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()``. +cela, il suffit de rajouter ``@hug.cli()`` comme nous l'avons fait avec ``@hug.get()``. + hug et le versioning ==================== From f5c21e0809d398b9318c34e07131ebea17f599e6 Mon Sep 17 00:00:00 2001 From: OmbicheFlag Date: Thu, 15 Jun 2017 00:19:53 +0200 Subject: [PATCH 33/33] Create index.rst --- source/hug/index.rst | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/source/hug/index.rst b/source/hug/index.rst index 87adfee9..ecc49cf0 100644 --- a/source/hug/index.rst +++ b/source/hug/index.rst @@ -46,10 +46,12 @@ 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. + Les formats d'échanges sont nombreux. Dans ce chapitre, nous resterons sur du @@ -138,14 +140,13 @@ On peut remarquer que la documentation est très claire, la clé overview nous r 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()``. +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.