如何在Python中接收Github Webhooks
Github提供了一种功能,当你的代码库有活动时,可以把信息发送到你指定的URL,这个功能叫做Post-receive hooks。我想写一个小的Python命令行程序(也就是没有图形界面或网页应用),这个程序会在我的电脑上(以后可能会放在NAS上)持续监听这些来自Github的POST请求。一旦收到Github发来的POST请求,它就会处理里面的JSON信息。处理这些JSON数据对我来说没问题。
这些POST请求可能只会来自Github提供的少数几个IP地址;我打算/希望能指定一个端口,让请求发送到我的电脑上。
问题是,我对网络技术了解得不够,搜索时看到的选项太多了……我该用Django、Requests、sockets、Flask,还是微框架呢?我对大多数术语的意思都不太清楚,而且听起来很多都太复杂,解决不了我的问题——我感到有点不知所措,不知道从哪里开始。
我找到的大多数关于POST/GET的教程似乎都是在讲如何发送或直接请求网站的数据,而不是持续监听数据。
我觉得这个问题其实并不难,一旦我知道该怎么做,就能用几行代码解决。有没有人能给我一些指引、教程、例子或者示例代码呢?
5 个回答
我会推荐使用:
https://github.com/carlos-jenkins/python-github-webhooks
你可以配置一个网络服务器来使用它,或者如果你只是想在没有网络服务器的情况下运行一个进程,你可以启动内置的服务器:
python webhooks.py
这样你就可以完成你所需要的所有功能。不过,这需要你在你的代码库和钩子里做一些设置。
抱歉来得有点晚,还顺便做了个自我宣传。
首先,网络是基于请求和响应的。也就是说,有人会请求你的链接,而你需要做出相应的回应。你的服务器应用会一直在一个端口上监听这个请求,你不需要为此担心。
下面是一个在 Flask
(我喜欢的微框架)中的类似版本:
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()
这里有一个示例运行,使用的是来自 github 的例子:
运行服务器(上面的代码保存在 sample.py
文件中):
burhan@lenux:~$ python sample.py
* Running on http://127.0.0.1:5000/
这是对服务器的请求,基本上就是github会做的事情:
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
这是服务器的输出:
New commit by: Chris Wanstrath
127.0.0.1 - - [27/Jan/2013 22:07:56] "POST / HTTP/1.1" 200 -
这里有一个简单的 web.py 示例,用来接收通过 POST 发送的数据,并对这些数据进行处理(在这个例子中,就是把它打印到标准输出):
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()
我使用 hurl.it 向它发送了一些数据(在此之前,我在路由器上转发了 8080 端口),然后看到了以下输出:
$ 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
你可以把打印的部分换成你自己的 JSON 数据处理代码。
要指定端口号,可以在运行脚本时加一个额外的参数:
$ python hooks.py 1234