<commit_before># -*- coding: utf-8 -*-

import os, sys, traceback, hmac, hashlib, time
import flask
from flask import Flask, Blueprint, request, g, json, jsonify, after_this_request
from ..core.env import config, logger, logging
from .exceptions import MeleeHTTPException, BadRequest, SignatureError, ServerError

class MeleeApp(object):

    def __init__(self, import_name):
        self.import_name = import_name
        self.app = Flask(import_name)

        self.logger = logging.getLogger('%s.api' % config.servicename)
        self.app.log = self.logger
        self.app.before_request(self.before_request)
        self.app.after_request(self.after_request)
        self.app.teardown_request(self.teardown_request)
        self.app.register_error_handler(Exception, self.error_handler)

        for code in [400, 401, 402, 403, 404, 405, 406, 408, 409, 410, 411, 412, 413, 414,
            415, 416, 417, 418, 422, 428, 429, 431, 500, 501, 502, 503, 504, 505]:
            self.app.register_error_handler(code, self.error_handler)

        @self.app.route('/')
        def helloworld():
            # return flask.make_response(('wellcome to melee!', 200, None))
            return 'wellcome to melee!'
        
        logger.info('STARTUP', 'meleeapp %s created' % config.servicename)

    def verify_signature(self, sig_kv, signature, content, timestamp):
        key = config.sigkey(str(sig_kv))
        if not key:
            return False
        rawdata = '%s%s'% (content, timestamp)
        if isinstance(content, unicode):
            rawdata = rawdata.encode('utf-8')
        sig = hmac.new(key, rawdata, hashlib.sha256).hexdigest().lower()
        return sig == signature.lower()

    def before_request(self):
        self.logger.debug('REQUEST', request.path, request.endpoint, request.values.to_dict(), request.headers.get('User-Agent'))
        g.rawdata = request.get_data(cache=True, parse_form_data=False)
        g.jsondata = {}
        if request.endpoint is None:
            return
        g.startms = int(time.time()*1000)

        content = request.values.get('content')
        signature = request.values.get('signature', '')
        sig_kv = request.values.get('sig_kv')
        timestamp = request.values.get('timestamp') or 0
        g.jsonpcallback = request.values.get('callback')

        if content:
            if not timestamp or (time.time()*1000)-int(timestamp) > 86400000:
                raise BadRequest(description='reqeust expired %s' % timestamp)

            if not self.verify_signature(sig_kv, signature, content, timestamp):
                raise SignatureError(description='Signature Not Correct.')
            try:
                g.jsondata = json.loads(content)
            except:
                g.jsondata = {}

        self.logger.debug('REQUEST', request.path, request.endpoint, g.jsondata)

    def teardown_request(self, exc):
        if exc:
            self.logger.error('SHOULD_NOT_HAPPEN','teardown_request, has exception:%s'%(exc))

    def after_request(self, response):
        if request.endpoint is None:
            return response
        if response is None:
            return response

        g.reqeust_cost = int(time.time()*1000) - g.startms

        if getattr(g, 'response_code', None) is None:
            code = response.status_code
        else:
            code = g.response_code

        # 支持jsonp, 解决ajax get 请求跨域问题
        #if g.jsonpcallback:
            #response.response = '%s(%s)' % (g.jsonpcallback, response.response)
        response.headers['Access-Control-Allow-Origin'] = '*'

        self.logger.info('REQUEST', request.remote_addr, request.method, g.reqeust_cost,
            request.path, request.headers.get('Content-Length', '0'), g.jsondata, 
            response.status_code, code, str(response.headers.get('Content-Length', '0')), response.response, request.headers.get('User-Agent'))

        return response

    def error_handler(self, error):
        self.logger.error('EXCEPTION', sys.exc_info()[1])
        self.logger.error('TRACEBACK', traceback.format_exc())
        
        if isinstance(error, MeleeHTTPException):
            g.response_code = error.code
            return jsonify(meta=error.info)
        else:
            error = ServerError(description='%s: %s' % (error.__class__.__name__, unicode(error)))
            g.response_code = error.code
            return jsonify(meta=error.info)


    def mount(self, blueprints, prefix=None):
        """bind the specific blueprints to the current flask app.
        :param blueprints: list, the list of blueprints
        :param prefix: dict, the url_prefix mapping definition for every blueprint
        Example Code:
            >>>blueprint = Blueprint('template', __name__, url_prefix='/test')
            >>>@blueprint.route('/foo')
            ...def foo():
            ...    return jsonify('foo ok')
            ...
            >>>meleeapp.mount([blueprint], prefix={'template': '/template'})
        now you can access the url 'http://host:port/template/test/xxx'
        """
        if not blueprints:
            return
        for b in blueprints:
            if prefix and b.name in prefix:
                url_prefix = '%s%s' % (prefix[b.name], b.url_prefix or '')
            else:
                url_prefix = b.url_prefix
            self.app.register_blueprint(b, url_prefix=url_prefix)
            self.logger.info('STARTUP', 'register blueprint: %s' % url_prefix)


    def __call__(self, environ, start_response):
        """Mark this MeleeApp as a WSGI App
        So all middleware that support WSGI protoal can run the instance of it.
        """
        return self.app(environ, start_response)<commit_msg>log the blueprint name during mount operation<commit_after># -*- coding: utf-8 -*-

import os, sys, traceback, hmac, hashlib, time
import flask
from flask import Flask, Blueprint, request, g, json, jsonify, after_this_request
from ..core.env import config, logger, logging
from .exceptions import MeleeHTTPException, BadRequest, SignatureError, ServerError

class MeleeApp(object):

    def __init__(self, import_name):
        self.import_name = import_name
        self.app = Flask(import_name)

        self.logger = logging.getLogger('%s.api' % config.servicename)
        self.app.log = self.logger
        self.app.before_request(self.before_request)
        self.app.after_request(self.after_request)
        self.app.teardown_request(self.teardown_request)
        self.app.register_error_handler(Exception, self.error_handler)

        for code in [400, 401, 402, 403, 404, 405, 406, 408, 409, 410, 411, 412, 413, 414,
            415, 416, 417, 418, 422, 428, 429, 431, 500, 501, 502, 503, 504, 505]:
            self.app.register_error_handler(code, self.error_handler)

        @self.app.route('/')
        def helloworld():
            # return flask.make_response(('wellcome to melee!', 200, None))
            return 'wellcome to melee!'
        
        logger.info('STARTUP', 'meleeapp %s created' % config.servicename)

    def verify_signature(self, sig_kv, signature, content, timestamp):
        key = config.sigkey(str(sig_kv))
        if not key:
            return False
        rawdata = '%s%s'% (content, timestamp)
        if isinstance(content, unicode):
            rawdata = rawdata.encode('utf-8')
        sig = hmac.new(key, rawdata, hashlib.sha256).hexdigest().lower()
        return sig == signature.lower()

    def before_request(self):
        self.logger.debug('REQUEST', request.path, request.endpoint, request.values.to_dict(), request.headers.get('User-Agent'))
        g.rawdata = request.get_data(cache=True, parse_form_data=False)
        g.jsondata = {}
        if request.endpoint is None:
            return
        g.startms = int(time.time()*1000)

        content = request.values.get('content')
        signature = request.values.get('signature', '')
        sig_kv = request.values.get('sig_kv')
        timestamp = request.values.get('timestamp') or 0
        g.jsonpcallback = request.values.get('callback')

        if content:
            if not timestamp or (time.time()*1000)-int(timestamp) > 86400000:
                raise BadRequest(description='reqeust expired %s' % timestamp)

            if not self.verify_signature(sig_kv, signature, content, timestamp):
                raise SignatureError(description='Signature Not Correct.')
            try:
                g.jsondata = json.loads(content)
            except:
                g.jsondata = {}

        self.logger.debug('REQUEST', request.path, request.endpoint, g.jsondata)

    def teardown_request(self, exc):
        if exc:
            self.logger.error('SHOULD_NOT_HAPPEN','teardown_request, has exception:%s'%(exc))

    def after_request(self, response):
        if request.endpoint is None:
            return response
        if response is None:
            return response

        g.reqeust_cost = int(time.time()*1000) - g.startms

        if getattr(g, 'response_code', None) is None:
            code = response.status_code
        else:
            code = g.response_code

        # 支持jsonp, 解决ajax get 请求跨域问题
        #if g.jsonpcallback:
            #response.response = '%s(%s)' % (g.jsonpcallback, response.response)
        response.headers['Access-Control-Allow-Origin'] = '*'

        self.logger.info('REQUEST', request.remote_addr, request.method, g.reqeust_cost,
            request.path, request.headers.get('Content-Length', '0'), g.jsondata, 
            response.status_code, code, str(response.headers.get('Content-Length', '0')), response.response, request.headers.get('User-Agent'))

        return response

    def error_handler(self, error):
        self.logger.error('EXCEPTION', sys.exc_info()[1])
        self.logger.error('TRACEBACK', traceback.format_exc())
        
        if isinstance(error, MeleeHTTPException):
            g.response_code = error.code
            return jsonify(meta=error.info)
        else:
            error = ServerError(description='%s: %s' % (error.__class__.__name__, unicode(error)))
            g.response_code = error.code
            return jsonify(meta=error.info)


    def mount(self, blueprints, prefix=None):
        """bind the specific blueprints to the current flask app.
        :param blueprints: list, the list of blueprints
        :param prefix: dict, the url_prefix mapping definition for every blueprint
        Example Code:
            >>>blueprint = Blueprint('template', __name__, url_prefix='/test')
            >>>@blueprint.route('/foo')
            ...def foo():
            ...    return jsonify('foo ok')
            ...
            >>>meleeapp.mount([blueprint], prefix={'template': '/template'})
        now you can access the url 'http://host:port/template/test/xxx'
        """
        if not blueprints:
            return
        for b in blueprints:
            if prefix and b.name in prefix:
                url_prefix = '%s%s' % (prefix[b.name], b.url_prefix or '')
            else:
                url_prefix = b.url_prefix
            self.app.register_blueprint(b, url_prefix=url_prefix)
            self.logger.info('STARTUP', 'register blueprint %s: %s' % (b.name, url_prefix))


    def __call__(self, environ, start_response):
        """Mark this MeleeApp as a WSGI App
        So all middleware that support WSGI protoal can run the instance of it.
        """
        return self.app(environ, start_response)
{'fraction_non_alphanumeric': 0.1201885310290652, 'fraction_numerical': 0.020249629047743738, 'mean_word_length': 2.44705174488568, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5033065', 'n_tokens_mistral': 3563, 'n_tokens_neox': 3279, 'n_words': 791}