def before_request():
    """This runs before every API request. The function take cares of creating
    driver object is not already created. Also it checks for few prerequisits
    parameters and set global variables for other functions to use
    
    Required paramters for an API hit are:
    auth-key: key string to identify valid request
    client_id: to identify for which client the request is to be run
    """
    global logger
    
    if not request.url_rule:
        abort(404)

    if logger == None:
        create_logger()
    logger.info("API call " + request.method + " " + request.url)

    auth_key = request.headers.get('auth-key')
    g.client_id = request.headers.get('client_id')
    rule_parent = request.url_rule.rule.split('/')[1]
    
    if API_KEY and auth_key != API_KEY:
        abort(401, 'you must send valid auth-key')
        raise Exception()

    if not g.client_id and rule_parent != 'admin':
        abort(400, 'client ID is mandatory')

    acquire_semaphore(g.client_id)

    # Create a driver object if not exist for client requests.
    if rule_parent != 'admin':
        if g.client_id not in drivers:
            drivers[g.client_id] = init_client(g.client_id)
        
        g.driver = drivers[g.client_id]
        g.driver_status = WhatsAPIDriverStatus.Unknown
        
        if g.driver is not None:
            g.driver_status = g.driver.get_status()
        
        # If driver status is unkown, means driver has closed somehow, reopen it
        if (g.driver_status != WhatsAPIDriverStatus.NotLoggedIn
            and g.driver_status != WhatsAPIDriverStatus.LoggedIn):
            drivers[g.client_id] = init_client(g.client_id)
            g.driver_status = g.driver.get_status()
        
        init_timer(g.client_id)