简体   繁体   English

如何在 Python 中接收 Github Webhooks

[英]How do I receive Github Webhooks in Python

Github offers to send Post-receive hooks to an URL of your choice when there's activity on your repo. Github 提供在你的 repo 上有活动时将Post-receive hooks发送到你选择的 URL。 I want to write a small Python command-line/background (ie no GUI or webapp) application running on my computer (later on a NAS), which continually listens for those incoming POST requests, and once a POST is received from Github, it processes the JSON information contained within.我想编写一个在我的计算机上运行的小型Python 命令行/后台(即没有 GUI 或 webapp)应用程序(后来在 NAS 上),它不断地侦听那些传入的 POST 请求,一旦从 Github收到一个 POST,它处理其中包含的 JSON 信息。 Processing the json as soon as I have it is no problem.有了它就立即处理 json 没问题。 The POST can come from a small number of IPs given by github; POST 可以来自 github 给出的少量 IP; I plan/hope to specify a port on my computer where it should get sent.我计划/希望在我的计算机上指定一个端口来发送它。

The problem is, I don't know enough about web technologies to deal with the vast number of options you find when searching.. do I use Django, Requests, sockets,Flask, microframeworks...?问题是,我对 Web 技术了解得不够多,无法处理您在搜索时发现的大量选项……我是否使用 Django、Requests、sockets、Flask、微框架……? I don't know what most of the terms involved mean, and most sound like they offer too much/are too big to solve my problem - I'm simply overwhelmed and don't know where to start.我不知道所涉及的大多数术语是什么意思,而且大多数听起来像是它们提供的太多/太大而无法解决我的问题 - 我只是不知所措,不知道从哪里开始。

Most tutorials about POST/GET I could find seem to be concerned with either sending or directly requesting data from a website, but not with continually listening for it.我能找到的大多数关于 POST/GET 的教程似乎都与从网站发送或直接请求数据有关,但与持续监听数据无关。

I feel the problem is not really a difficult one, and will boil down to a couple of lines, once I know where to go/how to do it.我觉得这个问题并不难,一旦我知道去哪里/如何做,就会归结为几行。 Can anybody offer pointers/tutorials/examples/sample code?任何人都可以提供指针/教程/示例/示例代码吗?

First thing is, web is request-response based.首先,Web 是基于请求-响应的。 So something will request your link, and you will respond accordingly.所以有些东西会请求你的链接,你会相应地做出回应。 Your server application will be continuously listening on a port;您的服务器应用程序将持续监听一个端口; that you don't have to worry about.你不必担心。

Here is the similar version in Flask (my micro framework of choice):这是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()

Here is a sample run, using the example from github :这是一个示例运行,使用来自 github示例

Running the server (the above code is saved in sample.py ):运行服务器(上面的代码保存在sample.py ):

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

Here is a request to the server, basically what github will do:这是对服务器的请求,基本上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

Here is the output at the server:这是服务器上的输出:

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

Here's a basic web.py example for receiving data via POST and doing something with it (in this case, just printing it to stdout):这是一个基本的 web.py 示例,用于通过 POST 接收数据并对其进行处理(在这种情况下,只需将其打印到 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()

I POSTed some data to it using hurl.it (after forwarding 8080 on my router), and saw the following output:我使用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

You should be able to swap out the print statements for your JSON processing.您应该能够为您的 JSON 处理换出打印语句。

To specify the port number, call the script with an extra argument:要指定端口号,请使用额外的参数调用脚本:

$ python hooks.py 1234 

I would use:我会用:

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

You can configure a web server to use it, or if you just need a process running there without a web server you can launch the integrated server:您可以配置一个 Web 服务器来使用它,或者如果您只需要一个没有 Web 服务器的进程在那里运行,您可以启动集成服务器:

python webhooks.py

This will allow you to do everything you said you need.这将允许您执行您所说的一切所需。 It, nevertheless, requires a bit of setup in your repository and in your hooks.然而,它需要在您的存储库和钩子中进行一些设置。

Late to the party and shameless autopromotion, sorry.迟到了,无耻的自动促销,对不起。

If you are using Flask , here's a very minimal code to listen for webhooks:如果您使用Flask ,这里有一个非常小的代码来监听 webhooks:

from flask import Flask, request, Response

app = Flask(__name__)

@app.route('/webhook', methods=['POST'])
def respond():
    print(request.json) # Handle webhook request here
    return Response(status=200)

And the same example using Django :使用Django的相同示例:

from django.http import HttpResponse
from django.views.decorators.http import require_POST

@require_POST
def example(request):
    print(request.json) # Handle webhook request here
    return HttpResponse('Hello, world. This is the webhook response.')

If you need more information, here's a great tutorial on how to listen for webhooks with Python .如果您需要更多信息,这里有一个关于如何使用 Python 侦听 webhooks的精彩教程。

If you're looking to watch for changes in any repo...如果你想观察任何回购中的变化......

1. If you own the repo that you want to watch 1.如果您own想要观看的回购

  • In your repo page, Go to settings在您的回购页面中,转到设置
  • click webhooks, new webhook (top right)单击 webhooks,新 webhook(右上角)
  • give it your ip/endpoint and setup everything to your liking给它你的 ip/endpoint 并根据你的喜好设置一切
  • use any server to get notified使用任何服务器获取通知

2. Not your Repo 2. 不是你的回购

response = requests.get("https://github.com/fire17/gd-xo/commits/master.atom").text response.split("<updated>")[1].split("</updated>")[0] '2021-08-06T19:01:53Z'
  • make a loop that checks this every so often and if this string has changed, then you can initiate a clone/pull request or do whatever you like :)创建一个循环,每隔一段时间检查一次,如果此字符串已更改,则您可以发起克隆/拉取请求或做任何您喜欢的事情:)

I'm so happy to finally achieve this capability.我很高兴终于实现了这种能力。

Hope this helped!希望这有帮助!

Great responses.很棒的反应。

I'm new to Flask.我是烧瓶的新手。 I have a question on how to make sure that the webhook calls the flask program.我有一个关于如何确保 webhook 调用烧瓶程序的问题。 Do we need to always run the script that has the flask code or once the application triggers the webhook and hits por 5000. The flask program will run automatically.我们是否需要一直运行带有flask 代码的脚本,或者一旦应用程序触发webhook 并命中por 5000。flask 程序将自动运行。

Thanks in advance!!提前致谢!!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM