Initial commit
All checks were successful
continuous-integration/drone Build is passing

This commit is contained in:
2021-11-16 20:40:17 +01:00
commit eb9193451e
20 changed files with 598 additions and 0 deletions

View File

@@ -0,0 +1,79 @@
#!/usr/bin/env python3
import sentry_sdk
from sentry_sdk.integrations.flask import FlaskIntegration
from flask import Flask
from werkzeug.middleware.proxy_fix import ProxyFix
# import stuff
from utils import register_all_error_handlers, register_health_checks, influxdb_instance
# import views
from views import ReportView
from config import Config
# Tracing stuffs
import jaeger_client
import opentracing
from flask_opentracing import FlaskTracing
# Setup sentry
if Config.SENTRY_DSN:
sentry_sdk.init(
dsn=Config.SENTRY_DSN,
integrations=[FlaskIntegration()],
traces_sample_rate=0,
send_default_pii=True,
release=Config.RELEASE_ID,
environment=Config.RELEASEMODE
)
# create flask app
app = Flask(__name__)
app.config.from_object(Config)
app.wsgi_app = ProxyFix(app.wsgi_app, x_proto=1)
# init stuff
influxdb_instance.init_app(app)
# register error handlers
register_all_error_handlers(app)
# Setup tracing
def initialize_tracer():
app.logger.info("Initializing jaeger...")
jaeger_cfg = jaeger_client.Config(config={}, service_name='birb-latency-collector', validate=True)
tracer = jaeger_cfg.initialize_tracer()
return tracer
tracing = FlaskTracing(initialize_tracer, True, app)
# register views
for view in [ReportView]:
view.register(app, trailing_slash=False)
register_health_checks(app)
# start debugging if needed
if __name__ == "__main__":
app.run(debug=True)
else:
import os
if "gunicorn" in os.environ.get("SERVER_SOFTWARE", ""):
import logging
gunicorn_logger = logging.getLogger('gunicorn.error')
app.logger.handlers = gunicorn_logger.handlers
app.logger.setLevel(gunicorn_logger.level)
jaeger_logger = logging.getLogger('jaeger_tracing')
jaeger_logger.handlers = gunicorn_logger.handlers
jaeger_logger.setLevel(gunicorn_logger.level)
app.logger.info("Gunicorn environment detected!")
else:
app.logger.info("Not gunicorn")

View File

@@ -0,0 +1,17 @@
import os
class Config:
SECRET_KEY = os.environ.get('SECRET_KEY', os.urandom(12))
SENTRY_DSN = os.environ.get("SENTRY_DSN")
RELEASE_ID = os.environ.get("RELEASE_ID", "test")
RELEASEMODE = os.environ.get("RELEASEMODE", "dev")
INFLUXDB_HOST = os.environ['INFLUXDB_HOST']
INFLUXDB_PORT = os.environ['INFLUXDB_PORT']
INFLUXDB_USER = os.environ['INFLUXDB_USER']
INFLUXDB_PASSWORD = os.environ['INFLUXDB_PASSWORD']
INFLUXDB_DATABASE = os.environ['INFLUXDB_DATABASE']
INFLUXDB_TIMEOUT = 30

View File

@@ -0,0 +1 @@
#!/usr/bin/env python3

View File

@@ -0,0 +1 @@
import os

View File

@@ -0,0 +1,5 @@
#!/usr/bin/env python3
from .require_decorators import json_required
from .error_handlers import register_all_error_handlers
from .healthchecks import register_health_checks
from .influx import influxdb_instance

View File

@@ -0,0 +1,20 @@
#!/usr/bin/env python3
from flask import jsonify
def get_standard_error_handler(code: int):
def error_handler(err):
return jsonify({"msg": err.description, "status": code}), code
return error_handler
def register_all_error_handlers(app):
"""
function to register all handlers
"""
error_codes_to_override = [404, 403, 401, 405, 400, 409, 422]
for code in error_codes_to_override:
app.register_error_handler(code, get_standard_error_handler(code))

View File

@@ -0,0 +1,19 @@
#!/usr/bin/env python3
from .influx import influxdb_instance
from healthcheck import HealthCheck
from flask import Flask
def health_database_status():
try:
version = influxdb_instance.connection.ping()
except Exception as e:
return False, str(e)
else:
return True, f'influxdb ({version}) is ok'
def register_health_checks(app: Flask):
health = HealthCheck()
health.add_check(health_database_status)
app.add_url_rule("/healthz", "healthcheck", view_func=lambda: health.run())

View File

@@ -0,0 +1,4 @@
#!/usr/bin/env python3
from flask_influxdb import InfluxDB
influxdb_instance = InfluxDB()

View File

@@ -0,0 +1,16 @@
#!/usr/bin/env python3
from flask import request, abort
from functools import wraps
def json_required(f):
@wraps(f)
def call(*args, **kwargs):
if request.is_json:
return f(*args, **kwargs)
else:
abort(400, "JSON required")
return call

View File

@@ -0,0 +1,2 @@
#!/usr/bin/env python3
from .report_view import ReportView

View File

@@ -0,0 +1,7 @@
#!/usr/bin/env python3
from flask import jsonify, request, abort, current_app, Response
from flask_classful import FlaskView
class ReportView(FlaskView):
pass