Tout le monde peut le faire:
projet local -> github
Avec l'accès ssh (payant), vous pouvez faire ceci:
projet local -> PythonAnywhere
L'article montre comment (gratuitement) procéder:
projet local -> github -> PythonAnywhere
Tout d'abord, je vais vous expliquer pourquoi vous pourriez en avoir besoin, puis passer à la façon de le mettre en œuvre. N'hésitez pas à sauter l'article si la première partie ne vous intéresse pas.
Pourquoi?
PythonAnywhere est un excellent service! Il est gratuit, fournit une bonne puissance et même une base de données, vous pouvez donc créer un site dynamique en quelques minutes. C'est une excellente option pour les débutants qui veulent essayer quelque chose en direct et pour ceux qui ont besoin d'héberger une API ou un projet personnel.
Mais le service présente également des inconvénients. Et si vous voulez ouvrir le code sur lequel vous travaillez? Allez-vous soutenir et apporter des modifications à deux endroits à la fois? Une fois sur la production PythonAnywhere et une deuxième fois sur GitHub pour les autres développeurs. Que faire si vous acceptez Pull Request ou souhaitez intégrer CI? Dupliquer constamment toutes les actions est très gênant.
GitHub est un excellent service pour travailler ensemble et afficher le code source, leur interface utilisateur est meilleure que sur PythonAnywhere et, ce que je veux dire, éditer le code directement sur PythonAnywhere n'est pas très agréable. Et si nous pouvions combiner le meilleur des deux mondes?
Vous envoyez toutes les mises à jour sur GitHub et l'application PythonAnywhere se synchronise et redémarre automatiquement. Vous pouvez clignoter des RP, utiliser des tickets, afficher votre code depuis n'importe quel appareil sans même vous connecter et sans ouvrir un fichier dans l'éditeur de code - en général, faire tout ce que GitHub vous permet de faire.
J'entends déjà un murmure: "Bien, bien, convaincu, mais comment y parvenir?" Pas un mot de plus!
Comment?
Nous utilisons les webhooks Github pour vous informer d'une mise à jour d'application, la tirer et la recharger.
À titre d'exemple, je considérerai mon application SwagLyrics , dont je détiens le backend sur PythonAnywhere. J'utilise Flask, donc le processus sera différent pour un autre framework.
Tout d'abord, synchronisez le projet pour que GitHub soit à l'origine. Si vous n'avez pas encore créé de référentiel PythonAnywhere, vous pouvez l'initialiser ou le coder directement depuis GitHub.
Quelque chose comme:
git init git remote add origin https://github.com/yourusername/yourreponame.git
Maintenant, allez dans GitHub -> Paramètres -> Webhooks -> Ajouter un webhook
Vous y verrez:
Dans le champ "URL de la charge utile", ajoutez votre_domaine / route_to_update
Par exemple, le webhook de mon référentiel pointe vers nbsp; https://aadibajpai.pythonanywhere.com/update_server
Changez le "Type de contenu" de application / x-www-form-urlencoded en application / json (je vous expliquerai pourquoi cela est nécessaire un peu plus tard).
Nous ne toucherons pas encore au domaine secret.
Assurez-vous que l'option «événement push» est sélectionnée et cliquez sur «Ajouter un webhook».
Ouvrez votre application sur Flask, nous allons configurer un itinéraire pour recevoir des informations de GitHub lorsqu'un événement push se produit. Le chemin doit être celui que vous avez spécifié dans le champ «URL de la charge utile». Nous ne spécifions pas explicitement la branche principale, car pour simplifier, il est sous-entendu qu'il est le seul dans le référentiel.
La configuration la plus simple ressemblerait à ceci:
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
Ceci est l'exemple le plus trivial, une version plus complète sera inférieure.
Désormais, chaque fois qu'un événement push se produit, l'application se met à jour elle-même en faisant un pull.
Si tout s'est bien passé, voici ce que vous verrez après le prochain commit:
Avant de passer à la protection du webhook contre les étrangers, je vais vous dire comment redémarrer l'application après le tirage afin que vous n'ayez pas besoin de le faire manuellement.
Rechargement automatique des applications Web
Nous utiliserons des crochets git. Ce ne sont que des commandes shell exécutées après les événements. Il n'y a pas de crochet pour l'événement après le pull, mais ...
Nous utilisons le fait que git pull n'est rien d'autre que git fetch → git merge , mais un crochet pour l'événement après la fusion existe. Il est exécuté si l'extraction est terminée avec succès.
Dans votre référentiel PythonAnywhere, accédez à .git / hooks /
Il y aura déjà plusieurs hooks existants, ajoutez-y les vôtres en créant un fichier post-fusion
Écrivez-y le code suivant:
#!/bin/sh touch /path/to/username_pythonanywhere_com_wsgi.py
Utilisez le chemin d'accès à votre wsgi, qui, une fois modifié (toucher), redémarre l'application.
Pour rendre le fichier exécutable, ouvrez la console et exécutez
chmod +x post-merge
Assurez-vous que le redémarrage fonctionne en effectuant un nouveau commit.
Passons maintenant à la sécurisation d'un webhook.
Protection de Webhook
La protection d'un webhook est nécessaire pour que quelqu'un d'autre ne puisse pas constamment envoyer des demandes de redémarrage de l'application. Nous utiliserons ce guide.
Tout d'abord, ajoutez un jeton secret sur PythonAnywhere en tant que variable d'environnement, ainsi que dans le champ «Secret» des paramètres du webhook GitHub. Ici, le processus est décrit plus en détail.
GitHub donne ses méthodes en Ruby, mais nous utilisons Python, nous allons donc utiliser cette fonction de comparaison:
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)
Modifiez maintenant le contrôleur update_server pour vérifier si la signature est valide en ajoutant ces lignes avant la partie mise à jour du code:
x_hub_signature = request.headers.get('X-Hub-Signature') if not is_valid_signature(x_hub_signature, request.data, w_secret):
w_secret doit correspondre à la valeur que vous avez définie un peu plus tôt en tant que variable d'environnement.
En général, il est logique d'ajouter la journalisation et quelques vérifications supplémentaires pour vous assurer que le webhook GitHub ou que l'événement contient des données, donc si vous le souhaitez, vous pouvez copier le code pertinent de mon référentiel , en le changeant si nécessaire, car vous savez déjà tout l'important
J'espère que les informations vous ont été utiles. Je sais qu'il y a beaucoup de choses, mais je voulais que vous compreniez ce qui se passait.
Je n'ai pas tout trouvé moi-même, j'ai plutôt rassemblé les plus importants à partir de diverses sources et créé une solution complète.
Voici les liens qui m'ont aidé et peuvent vous aider: Merci d'avoir lu!