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