每个人都可以这样做:
本地项目-> github
使用(收费)ssh访问权限,您可以执行以下操作:
本地项目-> PythonAnywhere
本文显示了如何(免费)执行此操作:
本地项目-> github-> PythonAnywhere
首先,我将列出您可能需要它的原因,然后继续介绍如何实现它。 如果您对第一部分不感兴趣,请随时跳过本文。
怎么了
PythonAnywhere是一项很棒的服务! 它是免费的,提供强大的功能,甚至提供数据库,因此您可以在几分钟内创建一个动态站点。 对于想要尝试现场体验的初学者以及需要托管API或某些个人项目的人来说,这是一个很好的选择。
但是该服务也有缺点。 如果要打开正在处理的代码怎么办? 您会同时在两个地方支持并进行更改吗? 一次在PythonAnywhere生产中,第二次在GitHub上供其他开发人员使用。 如果您接受Pull Request或想要集成CI,该怎么办? 不断重复所有动作非常不便。
GitHub是一个很好的服务,可以一起工作和查看源代码,它们的UI比在PythonAnywhere上更好,而且,我的意思是,直接在PythonAnywhere上编辑代码不是很愉快。 如果我们可以将两个世界的优点结合起来怎么办?
您将所有更新推送到GitHub上,PythonAnywhere应用程序将自动同步并重新启动。 您可以在任何设备上闪烁PR,使用票证,从任何设备查看代码,甚至无需登录,也无需在代码编辑器中打开文件-通常,GitHub可以做的所有事情。
我已经听到一个杂音:“好,好,被说服,但是如何实现呢?” 一句话不多!
怎么了
我们使用Github Webhooks来通知您应用程序更新,拉动并重新加载它。
作为示例,我将考虑我的SwagLyrics应用程序,该应用程序的后端位于PythonAnywhere上。 我使用的是Flask,因此对于另一个框架,该过程将有所不同。
首先,同步项目,使GitHub成为源。 如果尚未创建PythonAnywhere存储库,则可以对其进行初始化或直接从GitHub对其进行编码。
类似于:
git init git remote add origin https://github.com/yourusername/yourreponame.git
现在转到GitHub->设置-> Webhooks->添加webhook
在那里,您将看到:
在“有效负载网址”字段中,添加your_domain / route_to_update
例如,我的存储库的webhook指向nbsp; https://aadibajpai.pythonanywhere.com/update_server
将“内容类型”从application / x-www-form-urlencoded更改为application / json (稍后再告诉您为什么需要这样做)。
我们不会触摸“秘密”字段。
确保选择了“推送事件”选项,然后单击“添加webhook”。
在Flask上打开您的应用程序,我们将配置一条路由,以在推送事件发生时从GitHub接收信息。 该路径应该是您在“有效载荷URL”字段中指定的路径。 我们没有明确指定master分支,因为 为了简单起见,它暗示它是存储库中唯一的一个。
最简单的设置如下所示:
from flask import Flask, request import git
app = Flask(__name__)
@app.route('/update_server', methods=['POST']) def webhook(): if request.method == 'POST': repo = git.Repo('path/to/git_repo') origin = repo.remotes.origin
origin.pull()
return 'Updated PythonAnywhere successfully', 200 else: return 'Wrong event type', 400
这是最简单的例子,一个完整的版本会更低。
现在,每当发生push事件时,应用程序都会通过pull进行更新。
如果一切顺利,则下一次提交后,您将看到以下内容:
在继续保护Webhook免受陌生人攻击之前,我将告诉您如何在拉动后重新启动应用程序,这样您就无需手动执行此操作。
Web应用程序自动重新加载
我们将使用git hooks。 这些只是事件后执行的shell命令。 拉动后没有事件挂钩,但是...
我们使用git pull仅仅是git fetch → git merge的事实,但是存在合并后事件的钩子。 如果拉取成功完成,将执行它。
在您的PythonAnywhere存储库中,转到.git / hooks /
现有的钩子已经存在,可以通过创建一个合并后的文件来添加自己的钩子
将以下代码写入其中:
#!/bin/sh touch /path/to/username_pythonanywhere_com_wsgi.py
使用您的wsgi的路径,该路径在更改(触摸)后将重新启动应用程序。
要使文件可执行,请打开控制台并运行
chmod +x post-merge
通过进行新的提交来确保重新启动有效。
现在让我们继续进行安全性。
Webhook保护
必须保护Webhook,以便其他人无法不断发送重新启动应用程序的请求。 我们将使用本指南。
首先,在PythonAnywhere上以及在GitHub webhook设置的“ Secret”字段中添加一个秘密令牌作为环境变量。 在此将更详细地描述该过程。
GitHub在Ruby中提供了其方法,但是我们使用Python,因此我们将使用以下比较功能:
import hmac import hashlib def is_valid_signature(x_hub_signature, data, private_key): # x_hub_signature and data are from the webhook payload # private key is your webhook secret hash_algorithm, github_signature = x_hub_signature.split('=', 1) algorithm = hashlib.__dict__.get(hash_algorithm) encoded_key = bytes(private_key, 'latin-1') mac = hmac.new(encoded_key, msg=data, digestmod=algorithm) return hmac.compare_digest(mac.hexdigest(), github_signature)
现在,通过在代码更新部分之前添加以下行来修改update_server控制器以检查签名是否有效:
x_hub_signature = request.headers.get('X-Hub-Signature') if not is_valid_signature(x_hub_signature, request.data, w_secret):
w_secret应该与您之前设置为环境变量的值匹配。
通常,添加日志记录和更多检查以确保GitHub Webhook或该事件包含数据是有意义的 ,因此,如果您愿意,您可以从我的存储库中复制相关代码 ,并在必要时进行更改,因为您已经知道了一切重要的
希望这些信息对您有所帮助。 我知道有很多事情,但是我希望您了解正在发生的事情。
我自己并没有提出所有建议,而是从各种渠道收集了最重要的建议,并创建了完整的解决方案。
感谢您的阅读!