Lire la dernière documentation - Parcourir le référentiel de code GitHub
Hug vise à rendre le développement d'API conduit au Python aussi simple que possible, mais pas plus simple. En conséquence, il simplifie considérablement le développement de l'API Python.
Objectifs de conception de Hug:
Faire du développement d'une API motivée par Python aussi succinct qu'une définition écrite.
Le cadre devrait encourager le code qui est autonome.
Ça devrait être rapide. Un développeur ne devrait jamais ressentir le besoin de chercher ailleurs pour des raisons de performance.
La rédaction de tests pour les API écrits sur les câlins doit être facile et intuitive.
La magie faite une fois, dans un framework API, est meilleure que de pousser le problème défini sur l'utilisateur du cadre API.
Soyez la base des API Python de prochaine génération, embrassant les dernières technologies.
À la suite de ces objectifs, Hug est Python 3+ uniquement et construit sur la bibliothèque HTTP haute performance de Falcon
Obtenez un câlin avec professionnel avec l'abonnement Tidelift
Le soutien professionnel à HUG est disponible dans le cadre de l'abonnement Tidelift. Tidelift offre aux équipes de développement de logiciels une seule source pour acheter et maintenir leur logiciel, avec des assurances de notes professionnelles des experts qui le connaissent le mieux, tout en s'intégrant de manière transparente aux outils existants.
L'installation d'un câlin est aussi simple que:
PIP3 Installer Hug - Opgrade
Idéalement, dans un environnement virtuel.
Créez une exemple API avec un simple point de terminaison en quelques lignes.
# Nom de fichier: happy_birthday.py "" "Une API de base (fonction unique) écrite à l'aide de HUG" "" Importer [email protected] ('/ happy_birthday') def happy_birthday (nom, âge: hug.types.number = 1): "" "Dit joyeux anniversaire à un utilisateur" "" return "joyeux {âge} anniversaire {nom}!". Format (** Locaux ())
Pour exécuter, à partir du type de ligne de commande:
hug -f happy_birthday.py
Vous pouvez accéder à l'exemple de votre navigateur à: localhost:8000/happy_birthday?name=hug&age=1
. Consultez ensuite la documentation de votre API à localhost:8000/documentation
Les paramètres peuvent également être codés dans l'URL (consultez happy_birthday.py
pour l'exemple entier).
@ Hug.get ('/ HELTER / {Event}') Def Greet (Event: Str): "" "Greets de manière appropriée (de http://blog.ketchum.com/how-to-write-10-common-liday -Greetings /) "" "Salutations =" Happy "If Event ==" Christmas ": Salutations =" Merry "If Event ==" Kwanzaa ": Salutations =" Joyous "If Event ==" Wishes ": Greetings =" Warm "return" {Salutations} {event}! ". Format (** Locals ())
Qui, une fois que vous exécutez le serveur comme ci-dessus, vous pouvez utiliser de cette façon:
curl http://localhost:8000/greet/wishes "Warm wishes!"
# nom de fichier: versioning_example.py "" "Un exemple simple d'un appel API HUG avec le versioning" "" Importer [email protected] ('/ echo', versions = 1) def echo (text): return [email protected] ('/ echo', versions = plage (2, 5)) def echo (texte): return "echo: {text}". format (** locaux ())
Pour exécuter l'exemple:
hug -f versioning_example.py
Ensuite, vous pouvez accéder à l'exemple à partir de localhost:8000/v1/echo?text=Hi
/ localhost:8000/v2/echo?text=Hi
ou accéder à la documentation de votre API à partir de localhost:8000
Remarque: Le versioning dans Hug prend automatiquement en charge à la fois l'en-tête de version ainsi que les spécifications basées sur l'URL directe.
Les décorateurs de la méthode http
de HUG ne modifient pas vos fonctions d'origine. Cela rend le test des API de câlins aussi simples que de tester les autres fonctions Python. De plus, cela signifie qu'interagir avec vos fonctions API dans un autre code Python est aussi simple que d'appeler Python uniquement des fonctions API. Hug facilite le test de la pile Python complète de votre API en utilisant le module hug.test
:
Importer hugImport happy_birthdayhug.test.get (happy_birthday, 'happy_birthday', {'name': 'Timothy', 'Age': 25}) # Renvoie un objet de réponse
Vous pouvez utiliser cet objet Response
pour les assertions de test (consultez test_happy_birthday.py
):
def tests_happy_birthday (): réponse = hug.test.get (happy_birthday, 'happy_birthday', {'name': 'Timothy', 'Age': 25}) Assert Response.status == http_200assert Response.Data n'est pas aucun
Hug expose une méthode magique __hug_wsgi__
sur chaque module API automatiquement. L'exécution de votre API basée sur des câlins sur n'importe quel serveur WSGI standard devrait être aussi simple que de le pointer sur module_name
: __hug_wsgi__
.
Par exemple:
uwsgi --http 0.0.0.0:8000 - Wsgi-File Exemples / Hello_world.py - callable __hug_wsgi__
Pour exécuter l'API d'exemple Hello World Hug.
Lors de la création d'une API en utilisant le cadre HUG, vous utilisez les concepts suivants:
Les décorateurs de méthode get
, post
, update
, etc.
@ hug.get () # <- est la méthode HUG Decoratordef hello_world (): renvoie "bonjour"
Hug utilise la structure de la fonction que vous décorez pour générer automatiquement la documentation pour les utilisateurs de votre API. Hug passe toujours une variable de demande, de réponse et API_VERSION à votre fonction si elles sont définies paramètres dans votre définition de fonction.
Tapez des fonctions d'annotations qui sont éventuellement attachées à vos méthodes Arguments pour spécifier comment l'argument est validé et converti en type python
@ hug.get () def math (numéro_1: int, numéro_2: int): #the: int après les deux arguments est le type annotationreturn numéro_1 + numéro_2
Les annotations de type alimentent également la génération de documentation automatique de hug
pour permettre aux utilisateurs de votre API quelles données fournissent.
Directives Fonctions qui sont exécutées avec les données de demande / réponse en fonction de la demande en tant qu'argument dans votre API_FUNCTION. Ceux-ci s'appliquent uniquement sous forme de paramètres d'entrée et ne peuvent pas être appliqués actuellement sous forme de formats de sortie ou de transformations.
@ hug.get () def test_time (Hug_timer): return {'time_taken': float (Hug_timer)}
Les directives sont accessibles via un argument avec un préfixe hug_
, ou en utilisant des annotations de type Python 3. Ce dernier est l'approche la plus moderne et est recommandée. Les directives déclarées dans un module sont accessibles en utilisant leur nom entièrement qualifié en tant qu'annotation de type (ex: module.directive_name
).
Mis à part le cas d'utilisation de la transformation d'entrée évidente, les directives peuvent être utilisées pour tuer les données dans vos fonctions API, même si elles ne sont pas présentes dans la chaîne de requête de la demande, le corps du poteau, etc. pour un exemple d'utilisation des directives de cette manière, Voir l'exemple d'authentification dans le dossier Exemples.
L'ajout de vos propres directives est simple:
@ hug.Directive () def Square (valeur = 1, ** Kwargs): '' 'Renvoie passé dans le paramètre multiplié par lui-même' '' de retour valeur * Valeur: Square = 10): Retour ValueTester () == 100
Pour l'exhaustivité, voici un exemple d'accès à la directive via l'approche du nom magique:
@ hug.Directive () def multiply (valeur = 1, ** kwargs): '' 'Renvoie passé dans le paramètre multiplié par lui-même' '' de retour valeur * [email protected] () @ hug.local () def Tester ( hug_multiply = 10): return hug_multiplytester () == 100
La sortie forme une fonction qui prend la sortie de votre fonction API et la forme pour le transport vers l'utilisateur de l'API.
@ hug.default_output_format () def my_output_formatter (data): return "String: {0}". format (data) @ hug.get (output = hug.output_format.json) def hello (): return {'hello': ' monde'}
Comme indiqué, vous pouvez facilement modifier le format de sortie pour une API entière ainsi qu'un appel API individuel
Entrée format une fonction qui prend le corps des données données à un utilisateur de votre API et les formats pour la manipulation.
@ hug.default_input_format ("application / json") def my_input_formatter (data): return ('résultats', hug.input_format.json (data)))
Les formateurs d'entrée sont mappés en fonction du content_type
des données de demande et effectuent uniquement l'analyse de base. L'analyse plus détaillée doit être effectuée par les annotations de type présents sur votre api_function
Les fonctions middleware qui sont appelées pour chaque demande de processus API HUG
@ hug.request_middleware () def process_data (request, réponse): request.env ['server_name'] = 'changé'@hug.response_middleware () def process_data (request, réponse, ressource): réponse.set_header (' myHeader ', 'Valeur')
Vous pouvez également ajouter facilement n'importe quel middleware de style Falcon en utilisant:
__hug __. http.add_middleware (middlewareObject ())
Le mappage des paramètres peut être utilisé pour remplacer les noms de paramètres déduits, par exemple. Pour les mots clés réservés:
Importer Marshmallow.fields en tant que champs ... @ Hug.get ('/ foo', map_params = {'From': 'from_date'}) # API Call utilise 'from'def get_foo_by_date (from_date: fields.datetime ()): return find_foo (from_date)
Les formateurs d'entrée sont mappés en fonction du content_type
des données de demande et effectuent uniquement l'analyse de base. L'analyse plus détaillée doit être effectuée par les annotations de type présents sur votre api_function
HUG vous permet d'organiser de grands projets de toutes les manières qui vous conviennent. Vous pouvez importer n'importe quel module qui contient des fonctions décorées de câlins (demande de manipulation, directives, types de types de conduite, etc.) et étendre votre API de base avec ce module.
Par exemple:
something.py
importer [email protected] ('/') def Say_hi (): renvoyez «Bonjour de quelque chose»
Peut être importé dans le fichier API principal:
__init__.py
Importer Hugfrom. importer quelque [email protected] ('/') def Say_hi (): renvoyez "salut de root" @ hug.extend_api ('/ quelque chose') def quelque chose_api (): return [quelque chose]
Ou alternativement - pour des cas comme celui-ci - où un seul module est inclus par voie URL:
# alternativementhug.api (__ nom __). Extend (quelque chose, '/ quelque chose')
Par défaut, HUG renvoie une spécification API générée automatiquement lorsqu'un utilisateur essaie d'accéder à un point final qui n'est pas défini. Si vous ne souhaitez pas retourner cette spécification, vous pouvez désactiver la documentation 404:
À partir de l'application de ligne de commande:
HUGS -ND -F {File} #nd Flag indique à Hug de ne pas générer de documentation sur 404
De plus, vous pouvez facilement créer un gestionnaire 404 personnalisé en utilisant le décorateur hug.not_found
:
@ hug.not_found () def not_found_handler (): renvoyer "non trouvé"
Ce décorateur fonctionne de la même manière que les décorateurs de méthode HTTP HUG, et est même conscient de la version:
@ hug.not_found (versions = 1) def not_found_handler (): return "" @ hug.not_found (versions = 2) def not_found_handler (): return "non trouvé"
Lorsque vous utilisez le décorateur de méthode get
et cli
sur Coroutines, HUG planifiera l'exécution de la coroutine.
Utilisation du décorateur d'asyncio coroutine
@ hug.get () @ asyncio.coroutinedf hello_world (): renvoie "bonjour"
Utilisation du mot-clé asynchronisé Python 3.5.
@ hug.get () async def hello_world (): renvoyer "bonjour"
Remarque: Hug fonctionne sur le Falcon supérieur, ce qui n'est pas un serveur asynchrone. Même si l'utilisation d'Asyncio, les demandes seront toujours traitées de manière synchrone.
Si vous aimez se développer dans Docker et garder votre système propre, vous pouvez le faire, mais vous devrez d'abord installer Docker Compose.
Une fois que vous avez fait cela, vous devrez cd
dans le répertoire docker
et exécuter le serveur Web (Gunicorn) spécifié dans ./docker/gunicorn/Dockerfile
, après quoi vous pouvez prévisualiser la sortie de votre API dans le navigateur de votre Machine hôte.
$ cd ./docker# Cela exécutera Gunicorn sur le port 8000 du conteneur Docker. $ docker-compose up gunicorn # de la machine hôte, trouvez votre adresse IP Dockers. # pour Windows & Mac: $ docker-machine ip default # pour Linux: $ ifconfig docker0 | grep 'inet' | Cut -d: -f2 | awk '{print $ 1}' | tête -N1
Par défaut, l'IP est 172.17.0.1. En supposant que c'est également l'IP que vous voyez, vous iriez ensuite sur http://172.17.0.1:8000/
dans votre navigateur pour afficher votre API.
Vous pouvez également vous connecter à un conteneur Docker que vous pouvez considérer votre espace de travail. Cet espace de travail a Python et PIP installé afin que vous puissiez utiliser ces outils dans Docker. Si vous devez tester l'interface CLI, par exemple, vous utiliseriez cela.
$ docker-compose run workspace bash
Sur votre conteneur Docker workspace
, le répertoire ./docker/templates
sur votre ordinateur hôte est monté sur /src
dans le conteneur Docker. Ceci est spécifié dans services
> app
de ./docker/docker-compose.yml
.
BASH-4.3 # CD / SRC bash-4.3 # arbre.├fiques └fiquesrs ├fiques anniversaire.py └fique 1 répertoire, 3 fichiers
Hug prend au sérieux la sécurité et la qualité. Cet objectif est la raison pour laquelle nous dépendons uniquement de composants testés en profondeur et utilisons des outils d'analyse statique (tels que le bandit et la sécurité) pour vérifier la sécurité de notre base de code. Si vous trouvez ou rencontrez des problèmes de sécurité potentiels, veuillez nous le faire savoir immédiatement afin que nous puissions les résoudre.
Pour signaler une vulnérabilité de sécurité, veuillez utiliser le contact de sécurité Tidelift. Tidelift coordonnera le correctif et la divulgation.
Hug signifie simplement un guide utile, espérons-le. Cela représente l'objectif du projet d'aider les développeurs à créer des API bien écrites et intuitives.
Merci et j'espère que vous trouverez cet câlin utile lorsque vous développez votre prochaine API Python!
~ Timothy Crosley