I have a config.ini file which contains some properties but I want to read the environment variables inside the config file.
[section1]
prop1:(from envrinment variable) or value1
Is this possible or do I have to write a method to take care of that?
I know this is late to the party, but someone might find this handy.
What you are asking after is value interpolation combined with os.environ.
Pyramid?
The logic of doing so is unusual and generally this happens if one has a pyramid server, (which is read by a config file out of the box) while wanting to imitate a django one (which is always set up to read os.environ).
If you are using pyramid, then pyramid.paster.get_app has the argument options: if you pass os.environ as the dictionary you can use %(variable)s in the ini. Not that this is not specific to pyramid.paster.get_app as the next section shows (but my guess is get_app is the case).
app.py
from pyramid.paster import get_app
from waitress import serve
import os
app = get_app('production.ini', 'main', options=os.environ)
serve(app, host='0.0.0.0', port=8000, threads=50)
production.ini:
[app:main]
sqlalchemy.url = %(SQL_URL)s
...
Configparse?
The above is using configparser basic interpolation.
Say I have a file called config.ini with the line
[System]
conda_location = %(CONDA_PYTHON_EXE)
The following will work...
import configparser, os
cfg = configparser.ConfigParser()
cfg.read('config.ini')
print(cfg.get('System', 'conda_location', vars=os.environ))
I think :thinking_face, use .env and in config.py from dotenv import load_dotenv() and in next line load_dotenv() and it will load envs from .env file
Related
I want to build a simple Slack bolt python project so I followed this document.
but when I use python_dotenv and then run my main file (app.py) I face this error:
As `installation_store` or `authorize` has been used, `token` (or SLACK_BOT_TOKEN env variable) will be ignored.
Although the app should be installed into this workspace, the AuthorizeResult (returned value from authorize) for it was not found.
NOTE: by deleting this line in the main file (app.py):
load_dotenv()
and use the export method for defining tokens, everything works correctly.
this is my main file:
import os
from dotenv import load_dotenv
from slack_bolt import App
from slack_bolt.adapter.socket_mode import SocketModeHandler
import logging
load_dotenv() # by deleting this file, the error will be gone, but I want using the dotenv pip
app = App(token=os.environ.get("SLACK_BOT_TOKEN"))
logger = logging.getLogger(__name__)
#app.message("hello")
def message_hello(message, say):
# say() sends a message to the channel where the event was triggered
say(f"Hey there <#{message['user']}>!")
# Start your app
if __name__ == "__main__":
SocketModeHandler(app, os.environ["SLACK_APP_TOKEN"]).start()
I don't know exactly why, but I removed extra keys in the .env file, and everything went fine.
in .env file:
before:
SLACK_APP_TOKEN=xapp-fake-token
SLACK_BOT_TOKEN=xoxb-fake-token
USER_TOKEN=xoxp-fake-token
SLACK_CLIENT_ID=aa.bb
SLACK_CLIENT_SECRET=YOUR_CLIENT_SECRET
SLACK_API_TOKEN_APP_LEGACY=xoxb-fake-token
SLACK_SIGNING_SECRET=YOUT_SIGNING_SECRET
after:
SLACK_APP_TOKEN=xapp-fake-token
SLACK_BOT_TOKEN=xoxb-fake-token
I have a file celery_test.py which should load the configuration settings for testing(config.test) in Django but instead, it loads configuration of Development(config.development)
from __future__ import absolute_import
import os
from django.conf import settings
from celery import Celery
os.environ.setdefault(
"DJANGO_SETTINGS_MODULE", "config.testing"
)
test_app = Celery('test')
test_app.config_from_object('django.conf:settings')
test_app.autodiscover_tasks()
print("Testing celery")
print(settings)
#test_app.task(bind=True)
def debug_task(self):
print('Request: {0!r}'.format(self.request))
When I am printing settings it printing config.development instead of config.testing. Can anyone help me here how to load config.testing?
Seeing that you use django I would suggest not actually overriding the settings file like this. Instead use the django.test.override_settings decorator to override the specific settings you want to change. This way you're always testing the most current settings file, so you don't have to keep both up-to-date.
More information is also in the documentation: https://docs.djangoproject.com/en/3.0/topics/testing/tools/#django.test.override_settings.
I can't really provide an example, since you don't provide any unittest example. But I hope the linked documentation is clear enough.
Assuming your are using pytest, you could put this in your pytest.ini file:
[pytest]
DJANGO_SETTINGS_MODULE = celery_test.py
Or use:
DJANGO_SETTINGS_MODULE=celery_test.py pytest
for a one-liner.
I am trying to read some environment variables into my ConfigParser file.
I was referring to this answer but I am getting
"InterpolationDepthError: Value interpolation too deeply recursive" error.
section: [amazon]
option : amazon_access_key
rawval : %(AMAZON_ACCESS_KEY)s
Here is the portion of my config file:
[amazon]
amazon_access_key=%(AMAZON_ACCESS_KEY)s
amazon_secret_key=%(AMAZON_SECRET_KEY)s
And this is what I am writing to call the file:
from ConfigParser import SafeConfigParser
import os
config = SafeConfigParser(os.environ)
config.read('config.txt')
When I am calling these variables directly in the "amazon" section, I get the above stated error.
When I call these variables in the "default" section, like:
[default]
aws_access_key=%(AMAZON_ACCESS_KEY)s
aws_secret_key=%(AMAZON_SECRET_KEY)s
[amazon]
amazon_access_key=%(aws_access_key)s
amazon_secret_key=%(aws_secret_key)s
I get the following error:
ConfigParser.InterpolationMissingOptionError: Bad value substitution:
section: [amazon]
option : amazon_access_key
key : aws_access_key
rawval : %(aws_access_key)s
What am I missing here?
Also, how can I have separate config files for local and production deployments? Currently, all the configurations are same for local and production environments.
from ConfigParser import SafeConfigParser
import ConfigParser
import os
class CaseConfigParser(SafeConfigParser):
def optionxform(self, optionstr):
return optionstr
config = CaseConfigParser(os.environ)
config.read('config.ini')
print config.get('amazon', 'amazon_access_key')
Explanation:
The problem here is with optionxform, which turns all options to lower case by default. eventually, it will have key and value equal, similar to following.
[amazon]
amazon_access_key=%(amazon_access_key)s
Another solution can be - change names of keys in config.txt NOT equal to env vars.
[amazon]
aak=%(AMAZON_ACCESS_KEY)s
and then
config = SafeConfigParser(os.environ)
config.read('config.ini')
print config.get('amazon', 'aak')
You should remember that the default section should be capitalised.
[DEFAULT]
Making this change should solve the problem.
In my main.py have the below code:
app.config.from_object('config.DevelopmentConfig')
In another module I used import main and then used main.app.config['KEY'] to get a parameter, but Python interpreter says that it couldn't load the module in main.py because of the import part. How can I access config parameters in another module in Flask?
Your structure is not really clear but by what I can get, import your configuration object and just pass it to app.config.from_object():
from flask import Flask
from <path_to_config_module>.config import DevelopmentConfig
app = Flask('Project')
app.config.from_object(DevelopmentConfig)
if __name__ == "__main__":
application.run(host="0.0.0.0")
if your your config module is in the same directory where your application module is, you can just use :
from .config import DevelopmentConfig
The solution was to put app initialization in another file (e.g: myapp_init_file.py) in the root:
from flask import Flask
app = Flask(__name__)
# Change this on production environment to: config.ProductionConfig
app.config.from_object('config.DevelopmentConfig')
Now to access config parameters I just need to import this module in different files:
from myapp_init_file import app
Now I have access to my config parameters as below:
app.config['url']
The problem was that I had an import loop an could not run my python app. With this solution everything works like a charm. ;-)
I have a file that contains all the variables my application needs:
config.py
AWS_KEY=1234
AWS_SECRET=5678
modules/db.py
from project.libraries import boto as boto
conn = boto.connect_dynamodb(
aws_access_key_id=AWS_KEY
aws_secret_access_key=AWS_SECRET)
How can I get the variables from config.py into modules/db.py?
(Or, is this the wrong approach?)
Thanks.
modules/db.py
import config
AWS_KEY = config.AWS_KEY
Alternatively,
from config import AWS_KEY, AWS_SECRET
Or, if you want to keep the config prefix,
import config
print config.AWS_KEY
Forgive me if you've already done so, but have you read about python modules?