def create_app(**config): """ Create the application and return it to the user :return: flask.Flask application """ if config: app = ADSFlask(__name__, local_config=config) else: app = ADSFlask(__name__) app.url_map.strict_slashes = False # Add end points api = Api(app) api.add_resource(IndexView, '/tugboat/index') api.add_resource(ClassicSearchRedirectView, '/tugboat/classicSearchRedirect') api.add_resource(BumblebeeView, '/tugboat/redirect') api.add_resource(SimpleClassicView, '/tugboat/ads') api.add_resource(ComplexClassicView, '/tugboat/adsabs') api.add_resource(ComplexClassicArXivView, '/tugboat/arxiv') api.add_resource(ComplexClassicPhysicsView, '/tugboat/physics') Discoverer(app) return app
def create_app(**config): app = ADSFlask(__name__, static_folder=None, local_config=config or {}) app.url_map.strict_slashes = False ## pysqlite driver breaks transactions, we have to apply some hacks as per ## http://docs.sqlalchemy.org/en/rel_0_9/dialects/sqlite.html#pysqlite-serializable if 'sqlite' in app.config.get('SQLALCHEMY_DATABASE_URI', None): from sqlalchemy import event engine = app.db.engine @event.listens_for(engine, "connect") def do_connect(dbapi_connection, connection_record): # disable pysqlite's emitting of the BEGIN statement entirely. # also stops it from emitting COMMIT before any DDL. dbapi_connection.isolation_level = None @event.listens_for(engine, "begin") def do_begin(conn): # emit our own BEGIN conn.execute("BEGIN") app.register_blueprint(bp) discoverer = Discoverer(app) class JsonResponse(Response): default_mimetype = 'application/json' app.response_class = JsonResponse return app
def __init__(self, app_name, *args, **kwargs): """ :param: app_name - string, name of the application (can be anything) :keyword: local_config - dict, configuration that should be applied over the default config (that is loaded from config.py and local_config.py) """ ADSFlask.__init__(self, app_name, *args, **kwargs)
def __init__(self, *args, **kwargs): ADSFlask.__init__(self, *args, **kwargs) # HTTP client is provided by requests module; it handles connection pooling # here we just set some headers we always want to use while sending a request self.client.headers.update({ 'Authorization': 'Bearer {}'.format(self.config.get("API_TOKEN", '')) })
def create_app(**config): """ Create the application and return it to the user :return: application """ if config: app = ADSFlask(__name__, static_folder=None, local_config=config) else: app = ADSFlask(__name__, static_folder=None) app.url_map.strict_slashes = False load_s3(app) # Register extensions watchman = Watchman(app, version=dict(scopes=[''])) api = Api(app) Discoverer(app) # Add the end resource end points api.add_resource(AuthenticateUserClassic, '/auth/classic', methods=['POST']) api.add_resource(AuthenticateUserTwoPointOh, '/auth/twopointoh', methods=['POST']) api.add_resource( ClassicLibraries, '/libraries/classic/<int:uid>', methods=['GET'] ) api.add_resource( TwoPointOhLibraries, '/libraries/twopointoh/<int:uid>', methods=['GET'] ) api.add_resource( ExportTwoPointOhLibraries, '/export/twopointoh/<export>', methods=['GET'] ) api.add_resource( ClassicMyADS, '/myads/classic/<int:uid>', methods=['GET'] ) api.add_resource(ClassicUser, '/user', methods=['GET']) api.add_resource(AllowedMirrors, '/mirrors', methods=['GET']) return app
def test_config(self): app = ADSFlask(u'test', local_config={ u'FOO': [u'bar', {}], u'SQLALCHEMY_DATABASE_URI': u'sqlite:///', }) self.assertEqual(app._config[u'FOO'], [u'bar', {}]) self.assertEqual(app.config[u'FOO'], [u'bar', {}]) self.assertTrue(app.db)
def create_app(**config): opath = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) if opath not in sys.path: sys.path.insert(0, opath) if config: app = ADSFlask(__name__, static_folder=None, local_config=config) else: app = ADSFlask(__name__, static_folder=None) app.url_map.strict_slashes = False ## pysqlite driver breaks transactions, we have to apply some hacks as per ## http://docs.sqlalchemy.org/en/rel_0_9/dialects/sqlite.html#pysqlite-serializable if 'sqlite' in app.config.get('SQLALCHEMY_DATABASE_URI', None): from sqlalchemy import event engine = app.db.engine @event.listens_for(engine, "connect") def do_connect(dbapi_connection, connection_record): # disable pysqlite's emitting of the BEGIN statement entirely. # also stops it from emitting COMMIT before any DDL. dbapi_connection.isolation_level = None @event.listens_for(engine, "begin") def do_begin(conn): # emit our own BEGIN conn.execute("BEGIN") # Note about imports being here rather than at the top level # I want to enclose the import into the scope of the create_app() # and not advertise any of the views; and yes, i'm importing # everything from inside views (everything in __all__) from . import views for o in inspect.getmembers(views, predicate=lambda x: inspect.ismodule(x)): for blueprint in inspect.getmembers( o[1], predicate=lambda x: isinstance(x, Blueprint)): app.register_blueprint(blueprint[1]) discoverer = Discoverer(app) class JsonResponse(Response): default_mimetype = 'application/json' app.response_class = JsonResponse """ @app.after_request def after_request_func(response): # by default (almost all our) responses are # mimetype application/json if 'Content-Type' not in response.headers: response.headers['Content-Type'] = 'application/json' return response """ return app
def create_app(**config): opath = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) if opath not in sys.path: sys.path.insert(0, opath) if config: app = ADSFlask(__name__, static_folder=None, local_config=config) else: app = ADSFlask(__name__, static_folder=None) app.url_map.strict_slashes = False ## pysqlite driver breaks transactions, we have to apply some hacks as per ## http://docs.sqlalchemy.org/en/rel_0_9/dialects/sqlite.html#pysqlite-serializable if 'sqlite' in app.config.get('SQLALCHEMY_DATABASE_URI', None): from sqlalchemy import event engine = app.db.engine @event.listens_for(engine, "connect") def do_connect(dbapi_connection, connection_record): # disable pysqlite's emitting of the BEGIN statement entirely. # also stops it from emitting COMMIT before any DDL. dbapi_connection.isolation_level = None @event.listens_for(engine, "begin") def do_begin(conn): # emit our own BEGIN conn.execute("BEGIN") # Note about imports being here rather than at the top level # I want to enclose the import into the scope of the create_app() # and not advertise any of the views; and yes, i'm importing # everything from inside views (everything in __all__) from . import views for o in inspect.getmembers(views, predicate=lambda x: inspect.ismodule(x)): for blueprint in inspect.getmembers(o[1], predicate=lambda x: isinstance(x, Blueprint)): app.register_blueprint(blueprint[1]) discoverer = Discoverer(app) return app
def create_app(**config): """ Create the application and return it to the user :return: flask.Flask application """ if config: app = ADSFlask(__name__, static_folder=None, local_config=config) else: app = ADSFlask(__name__, static_folder=None) app.url_map.strict_slashes = False api = Api(app) api.add_resource(Graphics, '/<string:bibcode>') Discoverer(app) return app
def create_app(self): '''Start the wsgi application''' local_config = { 'SQLALCHEMY_DATABASE_URI': self.postgresql_url, 'SQLALCHEMY_ECHO': False, 'TESTING': True, 'PROPAGATE_EXCEPTIONS': True, 'TRAP_BAD_REQUEST_ERRORS': True } app = ADSFlask(__name__, static_folder=None, local_config=local_config) return app
def create_app(**config): opath = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) if opath not in sys.path: sys.path.insert(0, opath) if config: app = ADSFlask(__name__, static_folder=None, local_config=config) else: app = ADSFlask(__name__, static_folder=None) app.url_map.strict_slashes = False if app.config['MINIFY']: minify(app=app, html=True, js=True, cssless=True, cache=False, fail_safe=True, bypass=[]) return app
def create_app(**config): opath = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) if opath not in sys.path: sys.path.insert(0, opath) if config: app = ADSFlask(__name__, static_folder=None, local_config=config) else: app = ADSFlask(__name__, static_folder=None) app.url_map.strict_slashes = False if app.config['MINIFY']: minify(app=app, html=True, js=True, cssless=True, cache=False, fail_safe=True, bypass=[]) Limiter(app, key_func=get_remote_address) FlaskRedisPool(app) if app.config['ENVIRONMENT'] == "localhost": app.debug = True return app
def create_app(**config): """Application factory""" app = ADSFlask(__name__, static_folder=None, local_config=config or {}) app.url_map.strict_slashes = False api = Api(app) api.add_resource(WordCloud, '/word-cloud') api.add_resource(AuthorNetwork, '/author-network') api.add_resource(PaperNetwork, '/paper-network') discoverer = Discoverer(app) return app
def create_app(): """ Create the application and return it to the user :return: flask.Flask application """ app = ADSFlask(__name__, static_folder=None) app.url_map.strict_slashes = False api = Api(app) api.add_resource(ObjectSearch, '/', '/<string:objects>', '/<string:objects>/<string:source>') api.add_resource(QuerySearch, '/query') api.add_resource(ClassicObjectSearch, '/nedsrv') discoverer = Discoverer(app) return app
def create_app(**config): """ Create the application and return it to the user :return: flask.Flask application """ if config: app = ADSFlask(__name__, static_folder=None, local_config=config) else: app = ADSFlask(__name__, static_folder=None) app.url_map.strict_slashes = False Discoverer(app) app.register_blueprint(bp) return app
def __init__(self, *args, **kwargs): ADSFlask.__init__(self, *args, **kwargs) # HTTP client is provided by requests module; it handles connection pooling # here we just set some headers we always want to use while sending a request self.client.headers.update({'Authorization': 'Bearer {}'.format(self.config.get("API_TOKEN", ''))})
def create_app(**config): """ Application factory :return configured flask.Flask application instance """ if config: app = ADSFlask(__name__, static_folder=None, local_config=config) else: app = ADSFlask(__name__, static_folder=None) app.url_map.strict_slashes = False ## pysqlite driver breaks transactions, we have to apply some hacks as per ## http://docs.sqlalchemy.org/en/rel_0_9/dialects/sqlite.html#pysqlite-serializable if 'sqlite' in app.config.get('SQLALCHEMY_DATABASE_URI', None): from sqlalchemy import event engine = app.db.engine @event.listens_for(engine, "connect") def do_connect(dbapi_connection, connection_record): # disable pysqlite's emitting of the BEGIN statement entirely. # also stops it from emitting COMMIT before any DDL. dbapi_connection.isolation_level = None @event.listens_for(engine, "begin") def do_begin(conn): # emit our own BEGIN conn.execute("BEGIN") api = Api(app) @api.representation('application/json') def json(data, code, headers): """ Since we force SOLR to always return JSON, it is faster to return JSON as text string directly, without parsing and serializing it multiple times """ if not isinstance(data, basestring): resp = jsonify(data) resp.status_code = code else: resp = make_response(data, code) resp.headers['Content-Type'] = 'application/json' resp.headers['Server'] = 'Solr Microservice {v}'.format( v=app.config.get('SOLR_SERVICE_VERSION')) if code == 200: resp.headers['Cache-Control'] = app.config.get( 'SOLR_CACHE_CONTROL', "public, max-age=600") if 'Set-Cookie' in headers: resp.headers['Set-Cookie'] = headers['Set-Cookie'] return resp api.add_resource(StatusView, '/status') api.add_resource(Tvrh, '/tvrh') api.add_resource(Search, '/query') api.add_resource(Qtree, '/qtree') api.add_resource(BigQuery, '/bigquery') Discoverer(app) return app
def create_app(self): '''Start the wsgi application''' local_config = {} app = ADSFlask(__name__, static_folder=None, local_config=local_config) 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
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