[PYTHON] Modèle pour Bottle lors du déploiement avec Github et Bitbucket

Un modèle pour votre propre Bottle.

Les API Bitbucket et Github Hook sont enregistrées sur le serveur d'API Upstart (gunicorn après avoir été tirées. )) Redémarre.

J'ai inclus GitPython pour travailler avec le référentiel Git.

Arrow est également inclus dans le traitement à l'époque.

server.py


# -*- coding: utf-8 -*-

import commands
import os.path
import traceback
from decorator import decorator
import logging
import subprocess
import getpass

from bottle import get, post, put, delete, run, default_app, request, response, HTTPError, redirect, local, abort 
from bottle import static_file, route

import arrow

from git import Repo


# Decorator

@decorator
def check_db_connection(func, *args, **kwargs):
    """
Pour Peewee. db est une instance de la base de données Peewee.
    """

    try:
        db.get_conn().ping(True)
    except:
        logging.error(traceback.format_exc())
    
    return func(*args, **kwargs)

@decorator
def check_login(func, *args, **kwargs):
    """
Ecrire le processus d'authentification et localiser l'instance utilisateur connecté.Mettez-le en moi ou quelque chose comme ça.
    """

    response_json = func(*args, **kwargs)
    return response_json

@decorator
def error_handling(func, *args, **kwargs):
    """
Renvoie l'erreur au format JSON. Pour le débogage. Au moment de cette publication, erreur_classe ou erreur_Supprimer la trace.
    """

    try:
        return func(*args, **kwargs)
    except Exception as exception:
        if issubclass(exception.__class__, HTTPError):
            raise exception
        else:
            logging.error(traceback.format_exc())

            return {
                "error_class": type(exception).__name__,
                "error_trace": traceback.format_exc(),
            }

@decorator
def measurement(func, *args, **kwargs):
    """
Mesurez le temps de traitement de l'API.
    """

    start_time = arrow.now()

    result = func(*args, **kwargs)

    print "Transaction time: {0} secs".format(arrow.now().float_timestamp - start_time.float_timestamp)

    return result


# API


# Static files

@route('/')
@route('/<filepath:path>')
def server_static(filepath = None):
    if filepath is None:
        filepath = 'index.html'

    root_path = u"Chemin racine Web"

    response = static_file(filepath, root = root_path)
    return response


# Pull from Bitbucket

@post('/__pull_from_bitbucket')
@error_handling
def pull_from_bitbucket():
    """
Pour la coopération Bitbucket.
Avec IP, limitez l'accès à cette API uniquement à partir de Bitbucket.
    """

    repository_path = "{0}/../../..".format(os.path.dirname(__file__))
    repository = Repo(repository_path)

    payload = request.json

    logging.info("payload: {0}".format(payload))
    branch = payload['push']['changes'][0]['new']['name']

    logging.info("Pull from Bitbucket: {0}: {1}".format(
        branch, repository.active_branch.path))

    if repository.active_branch.path.endswith(branch):
        repository.remotes[0].pull()

        reboot_gunicorn_command = ["/usr/bin/sudo", "/sbin/restart", "api-server"]
        output = subprocess.check_output(reboot_gunicorn_command)
        logging.info("Reboot API server: {0}: {1}".format(
            reboot_gunicorn_command, output))

    return {
    }


# Pull from GitHub

GITHUB_HOOK_SECRET = os.environ.get('GITHUB_HOOK_SECRET')

@post('/__pull_from_github')
@error_handling
def pull_from_github():
    """
Pour l'intégration GitHub.
Placez la clé secrète GitHub Hook dans la variable d'environnement.
    """

    sent_signature = request.headers.get('X-Hub-Signature')[5:]
    raw_payload = request.body.read()
    generated_signature = hmac.new(GITHUB_HOOK_SECRET, raw_payload, hashlib.sha1).hexdigest()

    if sent_signature == generated_signature:

        repository_path = "{0}/../../..".format(os.path.dirname(__file__))
        repository = Repo(repository_path)
    
        payload = request.json
    
        if payload['ref'] == repository.active_branch.path:
            logging.info("Pull from GitHub: {0}: {1}".format(payload['ref'], payload['head_commit']['id']))
            repository.remotes[0].pull()
    
            reboot_gunicorn_command = ["/bin/sudo", "/usr/bin/systemctl", "restart", "api_server"]
    
            logging.info("Reboot API server: {0}".format(reboot_gunicorn_command))
            return_code = subprocess.call(reboot_gunicorn_command)

    return {
    }




application = default_app()
if __name__ == '__main__':
    run(host = 'localhost', port = 8000, debug = True)

Recommended Posts

Modèle pour Bottle lors du déploiement avec Github et Bitbucket
Afficher les colonnes et les variables du numéro de série avec le modèle de bouteille
Comment gérer les erreurs lors de l'installation de whitenoise et du déploiement sur Heroku
Impressions et mémorandum lors de la première utilisation de VScode
sélénium: attendre l'élément avec ET / OU
Solution aux erreurs qui se produisent lors du déploiement sur Heroku
Connectez Scratch X et Digispark avec bouteille
Environnement et utilisation recommandés lors du développement avec Python
Raisonnement causal et recherche causale par Python (pour les débutants)
Ceci et cela utile lorsqu'il est utilisé avec nohup
Génération de configuration de réseau de modèles avec Python et Jinja2