web-dev-qa-db-fra.com

Comment recevoir des Webhooks Github en Python

Github propose d'envoyer hooks post-réception à une URL de votre choix quand il y a de l'activité sur votre repo. Je veux écrire une petite Python ligne de commande/arrière-plan (c'est-à-dire pas d'interface graphique ou d'application Web) en cours d'exécution sur mon ordinateur (plus tard sur un NAS), qui écoute continuellement les requêtes POST, et une fois POST est reçu de Github, il traite les informations JSON qu'il contient. Le traitement du json dès que je l'ai ne pose aucun problème Le POST peut provenir d'un petit nombre d'adresses IP fournies par github; je prévois/j'espère spécifier un port sur mon ordinateur où il devrait être envoyé.

Le problème est que je ne connais pas suffisamment les technologies web pour gérer le grand nombre d'options que vous trouvez lors de la recherche .. dois-je utiliser Django, Requests, sockets, Flask, microframeworks ...? Je ne sais pas ce que la plupart des termes impliqués signifient, et la plupart sonnent comme ils offrent trop/sont trop gros pour résoudre mon problème - je suis simplement dépassé et je ne sais pas par où commencer.

La plupart des didacticiels sur POST/GET que j'ai pu trouver semblent concerner l'envoi ou la demande directe de données à partir d'un site Web, mais pas l'écoute continue.

Je pense que le problème n'est pas vraiment difficile et se résumera à quelques lignes, une fois que je saurai où aller/comment le faire. Quelqu'un peut-il offrir des pointeurs/tutoriels/exemples/exemple de code?

32
Christoph

Voici un exemple basique de web.py pour recevoir des données via POST et faire quelque chose avec (dans ce cas, il suffit de l'imprimer sur stdout):

import web

urls = ('/.*', 'hooks')

app = web.application(urls, globals())

class hooks:
    def POST(self):
        data = web.data()
        print
        print 'DATA RECEIVED:'
        print data
        print
        return 'OK'

if __name__ == '__main__':
    app.run()

Je lui ai envoyé des données en utilisant hurl.it (après avoir transféré 8080 sur mon routeur), et j'ai vu la sortie suivante:

$ python hooks.py 
http://0.0.0.0:8080/

DATA RECEIVED: 
test=thisisatest&test2=25

50.19.170.198:33407 - - [27/Jan/2013 10:18:37] "HTTP/1.1 POST /hooks" - 200 OK

Vous devriez pouvoir échanger les instructions d'impression pour votre traitement JSON.

Pour spécifier le numéro de port, appelez le script avec un argument supplémentaire:

$ python hooks.py 1234 
22
ford

La première chose est que le Web est basé sur la demande-réponse. Quelque chose demandera votre lien et vous répondrez en conséquence. Votre application serveur écoutera en permanence sur un port; dont vous n'avez pas à vous soucier.

Voici la version similaire en Flask (mon micro framework de choix):

from flask import Flask, request
import json

app = Flask(__name__)

@app.route('/',methods=['POST'])
def foo():
   data = json.loads(request.data)
   print "New commit by: {}".format(data['commits'][0]['author']['name'])
   return "OK"

if __name__ == '__main__':
   app.run()

Voici un exemple d'exécution, en utilisant le exemple de github :

Exécution du serveur (le code ci-dessus est enregistré dans sample.py):

burhan@lenux:~$ python sample.py 
 * Running on http://127.0.0.1:5000/

Voici une demande au serveur, essentiellement ce que github fera:

burhan@lenux:~$ http POST http://127.0.0.1:5000 < sample.json
HTTP/1.0 200 OK
Content-Length: 2
Content-Type: text/html; charset=utf-8
Date: Sun, 27 Jan 2013 19:07:56 GMT
Server: Werkzeug/0.8.3 Python/2.7.3

OK # <-- this is the response the client gets

Voici la sortie sur le serveur:

New commit by: Chris Wanstrath
127.0.0.1 - - [27/Jan/2013 22:07:56] "POST / HTTP/1.1" 200 -
34
Burhan Khalid

J'utiliserais:

https://github.com/carlos-jenkins/python-github-webhooks

Vous pouvez configurer un serveur Web pour l'utiliser, ou si vous avez juste besoin d'un processus qui s'exécute sans serveur Web, vous pouvez lancer le serveur intégré:

python webhooks.py

Cela vous permettra de faire tout ce dont vous avez besoin. Cela nécessite néanmoins un peu de configuration dans votre référentiel et dans vos hooks.

Tard dans la fête et autopromotion éhontée, désolé.

1
Havok