Exemple #1
0
def create_app(app_name=None, instance_path=None, static_path=None,
               static_folder=None, **config):
    """Returns a :class:`Flask` application instance configured with common
    functionality for the AdsWS platform.

    :param app_name: application package name
    :param instance_path: application package path
    :param static_path: flask.Flask static_path kwarg
    :param static_folder: flask.Flask static_folder kwarg
    :param config: a dictionary of settings to override
    """
    # Flask application name
    app_name = app_name or '.'.join(__name__.split('.')[0:-1])

    # Force instance folder to always be located one level above adsws
    instance_path = instance_path or os.path.realpath(os.path.join(
        os.path.dirname(__file__), '../instance'
    ))

    # Create instance path
    try:
        if not os.path.exists(instance_path):
            os.makedirs(instance_path)
    except:
        pass

    app = ADSFlask(
        app_name,
        instance_path=instance_path,
        instance_relative_config=False,
        static_path=static_path,
        static_folder=static_folder,
        local_config=config or {}
    )

    # Handle both URLs with and without trailing slashes by Flask.
    app.url_map.strict_slashes = False

    load_config(app, config)

    # Ensure SECRET_KEY has a value in the application configuration
    register_secret_key(app)

    # ====================
    # Application assembly
    # ====================
    # Initialize application registry, used for discovery and loading of
    # configuration, extensions and Invenio packages
    Registry(app=app)

    app.extensions['registry'].update(
        # Register packages listed in config
        packages=PackageRegistry(app))

    app.extensions['registry'].update(
        # Register extensions listed in config
        extensions=ExtensionRegistry(app),
        # Register blueprints
        blueprints=BlueprintAutoDiscoveryRegistry(app=app),
    )

    # Extend application config with configuration from packages (app config
    # takes precedence)
    ConfigurationRegistry(app)

    configure_a_more_verbose_log_exception(app)

    app.wsgi_app = HTTPMethodOverrideMiddleware(app.wsgi_app)

    app.before_request(set_translations)
    app.before_request(make_session_permanent)

    if app.config.get('PRODUCTION', False):
        app.wsgi_app = ProxyFix(
            app.wsgi_app,
            num_proxies=app.config.get('NUM_PROXIES', 2)
        )

    if app.config.get('HTTPS_ONLY', False):
        # Contains the x-forwarded-proto in the criteria already
        # only works if app.debug=False
        # permanent=True responds with 302 instead of 301
        SSLify(app, permanent=True)

    # Register custom error handlers
    if not app.config.get('DEBUG'):
        app.errorhandler(404)(on_404)
        app.errorhandler(401)(on_401)
        app.errorhandler(429)(on_429)
        app.errorhandler(405)(on_405)

    @oauth2.after_request
    def set_adsws_uid_header(valid, oauth):
        """
        If the user is authenticated, inject the header "X-adsws-uid" into
        the incoming request header
        """
        if current_user.is_authenticated():
            h = Headers(request.headers.items())
            h.add_header("X-Adsws-Uid", current_user.id)
            if current_user.ratelimit_level is not None:
                h.add_header(
                    "X-Adsws-Ratelimit-Level",
                    current_user.ratelimit_level
                )
            request.headers = h
        return valid, oauth
    return app
Exemple #2
0
def create_app(app_name=None,
               instance_path=None,
               static_path=None,
               static_folder=None,
               **config):
    """Returns a :class:`Flask` application instance configured with common
    functionality for the AdsWS platform.

    :param app_name: application package name
    :param instance_path: application package path
    :param static_path: flask.Flask static_path kwarg
    :param static_folder: flask.Flask static_folder kwarg
    :param config: a dictionary of settings to override
    """
    # Flask application name
    app_name = app_name or '.'.join(__name__.split('.')[0:-1])

    # Force instance folder to always be located one level above adsws
    instance_path = instance_path or os.path.realpath(
        os.path.join(os.path.dirname(__file__), '../instance'))

    # Create instance path
    try:
        if not os.path.exists(instance_path):
            os.makedirs(instance_path)
    except:
        pass

    app = ADSFlask(app_name,
                   instance_path=instance_path,
                   instance_relative_config=False,
                   static_path=static_path,
                   static_folder=static_folder,
                   local_config=config or {})

    # Handle both URLs with and without trailing slashes by Flask.
    app.url_map.strict_slashes = False

    load_config(app, config)

    # Ensure SECRET_KEY has a value in the application configuration
    register_secret_key(app)

    # ====================
    # Application assembly
    # ====================
    # Initialize application registry, used for discovery and loading of
    # configuration, extensions and Invenio packages
    Registry(app=app)

    app.extensions['registry'].update(
        # Register packages listed in config
        packages=PackageRegistry(app))

    app.extensions['registry'].update(
        # Register extensions listed in config
        extensions=ExtensionRegistry(app),
        # Register blueprints
        blueprints=BlueprintAutoDiscoveryRegistry(app=app),
    )

    # Extend application config with configuration from packages (app config
    # takes precedence)
    ConfigurationRegistry(app)

    configure_a_more_verbose_log_exception(app)

    app.wsgi_app = HTTPMethodOverrideMiddleware(app.wsgi_app)

    app.before_request(set_translations)
    app.before_request(make_session_permanent)
    app.before_request(cache_data_stream)

    if app.config.get('PRODUCTION', False):
        app.wsgi_app = ProxyFix(app.wsgi_app,
                                num_proxies=app.config.get('NUM_PROXIES', 2))

    if app.config.get('HTTPS_ONLY', False):
        # Contains the x-forwarded-proto in the criteria already
        # only works if app.debug=False
        # permanent=True responds with 302 instead of 301
        SSLify(app, permanent=True)

    # Register custom error handlers
    if not app.config.get('DEBUG'):
        app.errorhandler(404)(on_404)
        app.errorhandler(401)(on_401)
        app.errorhandler(429)(on_429)
        app.errorhandler(405)(on_405)

    @oauth2.after_request
    def set_adsws_uid_header(valid, oauth):
        """
        If the user is authenticated, inject the header "X-adsws-uid" into
        the incoming request header
        """
        h = Headers(request.headers.items())

        if current_user.is_authenticated():
            h.add_header("X-Adsws-Uid", current_user.id)

        if valid:
            level = oauth.client.ratelimit
            if level is None:
                level = 1.0
            h.add_header("X-Adsws-Ratelimit-Level", level)
        else:
            h.add_header("X-Adsws-Ratelimit-Level", 0.0)

        request.headers = h
        return valid, oauth

    @app.teardown_request
    def teardown_request(exception=None):
        """This function will close active transaction, if there is one
        but only if the session is not dirty - we don't want to do any
        magic (instead of a developer)
        
        use expire_on_commit=False doesn't have the same effect
        http://docs.sqlalchemy.org/en/latest/orm/session_api.html#sqlalchemy.orm.session.Session.commit
        
        The problems we are facing is that a new transaction gets opened
        when session is committed; consequent access to the ORM objects
        opens a new transaction (which never gets closed and is rolled back)
        """
        a = current_app
        if 'sqlalchemy' in a.extensions:  # could use self.db but let's be very careful
            sa = a.extensions['sqlalchemy']
            if hasattr(sa, 'db') and hasattr(
                    sa.db, 'session') and sa.db.session.is_active:
                if bool(sa.db.session.dirty):
                    sa.db.session.close()  # db server will do rollback
                else:
                    sa.db.session.commit()  # normal situation

    return app
Exemple #3
0
def create_app(app_name=None, instance_path=None, static_path=None,
               static_folder=None, **config):
    """Returns a :class:`Flask` application instance configured with common
    functionality for the AdsWS platform.

    :param app_name: application package name
    :param instance_path: application package path
    :param static_path: flask.Flask static_path kwarg
    :param static_folder: flask.Flask static_folder kwarg
    :param config: a dictionary of settings to override
    """
    # Flask application name
    app_name = app_name or '.'.join(__name__.split('.')[0:-1])

    # Force instance folder to always be located one level above adsws
    instance_path = instance_path or os.path.realpath(os.path.join(
        os.path.dirname(__file__), '../instance'
    ))

    # Create instance path
    try:
        if not os.path.exists(instance_path):
            os.makedirs(instance_path)
    except:
        pass

    app = ADSFlask(
        app_name,
        instance_path=instance_path,
        instance_relative_config=False,
        static_path=static_path,
        static_folder=static_folder,
        local_config=config or {}
    )

    # Handle both URLs with and without trailing slashes by Flask.
    app.url_map.strict_slashes = False

    load_config(app, config)

    # Ensure SECRET_KEY has a value in the application configuration
    register_secret_key(app)

    # ====================
    # Application assembly
    # ====================
    # Initialize application registry, used for discovery and loading of
    # configuration, extensions and Invenio packages
    Registry(app=app)

    app.extensions['registry'].update(
        # Register packages listed in config
        packages=PackageRegistry(app))

    app.extensions['registry'].update(
        # Register extensions listed in config
        extensions=ExtensionRegistry(app),
        # Register blueprints
        blueprints=BlueprintAutoDiscoveryRegistry(app=app),
    )

    # Extend application config with configuration from packages (app config
    # takes precedence)
    ConfigurationRegistry(app)

    configure_a_more_verbose_log_exception(app)

    app.wsgi_app = HTTPMethodOverrideMiddleware(app.wsgi_app)

    app.before_request(set_translations)
    app.before_request(make_session_permanent)
    app.before_request(cache_data_stream)

    if app.config.get('PRODUCTION', False):
        app.wsgi_app = ProxyFix(
            app.wsgi_app,
            num_proxies=app.config.get('NUM_PROXIES', 2)
        )

    if app.config.get('HTTPS_ONLY', False):
        # Contains the x-forwarded-proto in the criteria already
        # only works if app.debug=False
        # permanent=True responds with 302 instead of 301
        SSLify(app, permanent=True)

    # Register custom error handlers
    if not app.config.get('DEBUG'):
        app.errorhandler(404)(on_404)
        app.errorhandler(401)(on_401)
        app.errorhandler(429)(on_429)
        app.errorhandler(405)(on_405)

    @oauth2.after_request
    def set_adsws_uid_header(valid, oauth):
        """
        If the user is authenticated, inject the header "X-adsws-uid" into
        the incoming request header
        """
        h = Headers(request.headers.items())
        
        if current_user.is_authenticated():
            h.add_header("X-Adsws-Uid", current_user.id)
            
        if valid:    
            level = oauth.client.ratelimit
            if level is None:
                level = 1.0
            h.add_header("X-Adsws-Ratelimit-Level", level)
        else:
            h.add_header("X-Adsws-Ratelimit-Level", 0.0)
        
        request.headers = h
        return valid, oauth
    
    @app.teardown_request
    def teardown_request(exception=None):
        """This function will close active transaction, if there is one
        but only if the session is not dirty - we don't want to do any
        magic (instead of a developer)
        
        use expire_on_commit=False doesn't have the same effect
        http://docs.sqlalchemy.org/en/latest/orm/session_api.html#sqlalchemy.orm.session.Session.commit
        
        The problems we are facing is that a new transaction gets opened
        when session is committed; consequent access to the ORM objects
        opens a new transaction (which never gets closed and is rolled back)
        """
        a = current_app
        if 'sqlalchemy' in a.extensions: # could use self.db but let's be very careful
            sa = a.extensions['sqlalchemy']
            if hasattr(sa, 'db') and hasattr(sa.db, 'session') and sa.db.session.is_active:
                if bool(sa.db.session.dirty):
                    sa.db.session.close() # db server will do rollback
                else:
                    sa.db.session.commit() # normal situation
                
    return app
Exemple #4
0
def create_app(app_name=None,
               instance_path=None,
               static_path=None,
               static_folder=None,
               **config):
    """Returns a :class:`Flask` application instance configured with common
    functionality for the AdsWS platform.

    :param app_name: application package name
    :param instance_path: application package path
    :param static_path: flask.Flask static_path kwarg
    :param static_folder: flask.Flask static_folder kwarg
    :param config: a dictionary of settings to override
    """
    # Flask application name
    app_name = app_name or '.'.join(__name__.split('.')[0:-1])

    # Force instance folder to always be located one level above adsws
    instance_path = instance_path or os.path.realpath(
        os.path.join(os.path.dirname(__file__), '../instance'))

    # Create instance path
    try:
        if not os.path.exists(instance_path):
            os.makedirs(instance_path)
    except:
        pass

    app = ADSFlask(app_name,
                   instance_path=instance_path,
                   instance_relative_config=False,
                   static_path=static_path,
                   static_folder=static_folder,
                   local_config=config or {})

    # Handle both URLs with and without trailing slashes by Flask.
    app.url_map.strict_slashes = False

    load_config(app, config)

    # Ensure SECRET_KEY has a value in the application configuration
    register_secret_key(app)

    # ====================
    # Application assembly
    # ====================
    # Initialize application registry, used for discovery and loading of
    # configuration, extensions and Invenio packages
    Registry(app=app)

    app.extensions['registry'].update(
        # Register packages listed in config
        packages=PackageRegistry(app))

    app.extensions['registry'].update(
        # Register extensions listed in config
        extensions=ExtensionRegistry(app),
        # Register blueprints
        blueprints=BlueprintAutoDiscoveryRegistry(app=app),
    )

    # Extend application config with configuration from packages (app config
    # takes precedence)
    ConfigurationRegistry(app)

    configure_a_more_verbose_log_exception(app)

    app.wsgi_app = HTTPMethodOverrideMiddleware(app.wsgi_app)

    app.before_request(set_translations)
    app.before_request(make_session_permanent)

    if app.config.get('PRODUCTION', False):
        app.wsgi_app = ProxyFix(app.wsgi_app,
                                num_proxies=app.config.get('NUM_PROXIES', 2))

    if app.config.get('HTTPS_ONLY', False):
        # Contains the x-forwarded-proto in the criteria already
        # only works if app.debug=False
        # permanent=True responds with 302 instead of 301
        SSLify(app, permanent=True)

    # Register custom error handlers
    if not app.config.get('DEBUG'):
        app.errorhandler(404)(on_404)
        app.errorhandler(401)(on_401)
        app.errorhandler(429)(on_429)
        app.errorhandler(405)(on_405)

    @oauth2.after_request
    def set_adsws_uid_header(valid, oauth):
        """
        If the user is authenticated, inject the header "X-adsws-uid" into
        the incoming request header
        """
        if current_user.is_authenticated():
            h = Headers(request.headers.items())
            h.add_header("X-Adsws-Uid", current_user.id)
            if current_user.ratelimit_level is not None:
                h.add_header("X-Adsws-Ratelimit-Level",
                             current_user.ratelimit_level)
            request.headers = h
        return valid, oauth

    return app