A template for your own Bottle.
The API for Hook on Bitbucket and Github is an API server (gunicorn registered in Upstart after pulling. )) Is restarting.
I have included GitPython for working with the Git repository.
Arrow is also included in the processing around the time.
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):
"""
For Peewee. db is an instance of Peewee's database.
"""
try:
db.get_conn().ping(True)
except:
logging.error(traceback.format_exc())
return func(*args, **kwargs)
@decorator
def check_login(func, *args, **kwargs):
"""
Write the authentication process and localize the logged-in user instance.Put it in me or something.
"""
response_json = func(*args, **kwargs)
return response_json
@decorator
def error_handling(func, *args, **kwargs):
"""
Returns the error in JSON format. For debugging. At the time of this release, error_class or error_Delete 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):
"""
Measure the processing time of the 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"Web root path"
response = static_file(filepath, root = root_path)
return response
# Pull from Bitbucket
@post('/__pull_from_bitbucket')
@error_handling
def pull_from_bitbucket():
"""
For Bitbucket integration.
With IP, limit access to this API only from 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():
"""
For GitHub integration.
Put the secret key of GitHub Hook in the environment variable.
"""
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