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
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
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
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