Hi,
thanks for this awesome project, I set up a whole api with authentication and everything in 2 hours tops!!
Now I want to pass a configuration file for when I start an api; let's say I have a test api, a dev api and a production api, that all three should make requests on different databases (test, dev, prod), how can I pass the configuration to every function of every route?
Eg I want to be able to achieve this:
/channel:
get:
tags: [Channel]
operationId: app.elastic.channel
summary: Get channels
responses:
200:
description: Return Channels
schema:
type: array
items:
$ref: '#/definitions/Channels'
and in app/elastic.py i got the function:
def channel(config=configuration_object):
print "{}".format(config)
In Flask there is the app['config'] and current_app utilities that make this work, but I wonder how it can be achieved here.
Many thanks for the help!
@KarimJedda thanks for the positive feedback!
What do you want to achieve exactly? Do you want to have different configurations for different routes (operations)? Or do you want to use a global configuration?
Note: you can also use custom classes (with instance or static methods) to encapsulate your operations (example operationId: "mymodule.mysubmodule.MyClass.my_static_method").
You're welcome @hjacobs thanks for this amazing tool!
Well I want to use a global configuration for every route. This means if I start the api in development mode, i want the /channel route to call the function get_channel with configuration=dev. If I start the api in test mode, I want it to call the function get_channel with configuration=test.
This means, I want to put a global configuration variable somewhere here and make it available in all the route functions:
app = connexion.App(__name__)
app.add_api('app/settings/api.yaml')
application = app.app
if __name__ == '__main__':
app.run(port=8080, server='gevent')
It would be amazing to find a solution, because I am using a service to start lots of apis and I define the configuration at the service level. ( awesome_utility start --env=test, or awesome_utility start --env=dev ..)
Ok, found it!
import connexion
app = connexion.App(__name__)
app.add_api('app/settings/api.yaml')
application = app.app # at this point we got flask
application.config['environment'] = 'test'
if __name__ == '__main__':
app.run(port=8080, server='gevent')
from flask import current_app
def channels():
print current_app.config['environment'] # prints out 'test'
return "Hello world"
Does the job pretty well. So I have a shell script that sets the environment everytime (test, dev, prod, qa)
Thanks buddy!
When I try to do this exact same pattern, I get this exception
This typically means that you attempted to use functionality that needed to interface with the current application object in some way. To solve
this, set up an application context with app.app_context().
Anyone have a fix for this? I'm trying to do this:
__init__.py
import connexion
def create_app():
app = connexion.FlaskApp(__name__, specification_dir='./')
# app.app is the Flask app
app.app.config.from_envvar('APP_CONFIG_PATH')
app.add_api('api.yml')
from db import db_session
@app.app.teardown_appcontext
def shutdown_session(exception=None):
db_session.remove()
return app
if __name__ == "__main__":
create_app().run(port=5050)
db.py
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from flask import current_app
with current_app.app_context():
engine = create_engine(current_app.config.get('DATABASE_URI'), echo=True)
db_session = scoped_session(sessionmaker(autocommit=False, autoflush=False, bind=engine))
Base = declarative_base()
Base.query = db_session.query_property()
def init_db():
Base.metadata.create_all(bind=engine)
As you can see, I'm doing my best to follow Flask best practices by using an app factory and env-specific configuration files. While I'm able to store them in app.app.config, I can't access them anywhere else. I tried add app_context() above, but that does give me the error RuntimeError: Working outside of application context.
It appears this issue is still a problem in connexion 2.x. Can this issue be re-opened?
I'm also struggling with this. I cannot access the config variables or context stored when creating the app.
Are we just missing something or is this indeed an issue?
I gave up and did something else...
Still an issue.
Same problem as above, flask.current_app cannot get the context.
Sorry to +1, but can anyone comment on a workaround for this?
Sorry to +1, but can anyone comment on a workaround for this?
I'd suggest to open a new issue and reference this one there.
I tried with app_context and looks like it is working:
with app.app.app_context():
current_app.config['env'] = 'dev'
so in the routes file or whatever file you call in openapi file use this:
env = current_app.config['env']
I tried with app_context and looks like it is working:
with app.app.app_context(): current_app.config['env'] = 'dev'so in the routes file or whatever file you call in openapi file use this:
env = current_app.config['dev']
It should probably say env = current_app.config['env']?
I tried with app_context and looks like it is working:
with app.app.app_context(): current_app.config['env'] = 'dev'so in the routes file or whatever file you call in openapi file use this:
env = current_app.config['dev']It should probably say
env = current_app.config['env']?
Sorry, I did a typo mistake. Updated the comment. Thanks.
Most helpful comment
Ok, found it!
api.py
routes.py
Does the job pretty well. So I have a shell script that sets the environment everytime (test, dev, prod, qa)
Thanks buddy!