We are trying to use Pycharm as our IDE, and it’s hard to run some of our python scripts because they need environment variables. There is a way to set environment variables in Pycharm, but of course if we copy paste them, it kinda defeats the purpose of using Doppler (we have to remember to update them).
In Pycharm, there is also a way to run a shell script that runs before any python script is run. I suspect that’s the way to go, but my n00by shell skills are woefully inept.
I did experiment with using Python’s subprocess library to effectively run doppler run -- python3 app.py but I could not get breakpoints to work so its usefulness is limited. The code is below in case this gives you new ideas.
import subprocess
import sys
from signal import signal, SIGINT
app = subprocess.Popen(['doppler', 'run', '--', 'python', 'app.py'], stdout=subprocess.PIPE)
def signal_handler(sig, frame):
app.terminate()
sys.exit(0)
signal(SIGINT, signal_handler)
while app.poll() is None:
line = app.stdout.readline().decode('utf-8')
sys.stdout.write(line)
Awesome, thanks! This is super helpful. My way of copy pasting was way clunkier, so this will definitely be a step up.
Speaking of, is there any shell script that can load the doppler secrets into the environment? Where you said, “[you weren’t] able to find a nice solution like running a script prior to the Python command to populate the environment variables”, I wasn’t sure if that meant that it’s not possible using Doppler, or you couldn’t find a way to run a pre-execution shell script in Pycharm. If latter, see screenshot; under “Before Launch” in configuration, one can select “External tool”, which can be a shell script.
So I dug further into configuring Doppler as an external tool via an external script but this doesn’t work because Pycharm executes the script using /bin/bash meaning it is executed in a subshell and therefore, any variables exported there are not visible to the subsequent Python script.
I’ve got two more ideas for you though.
1. Manually populate env vars during development
The example here I’ll use is a Flask app that requires a HOSTNAME and PORT vars from Doppler.
You could check to see if you’re running in a development environment, e.g. os.environ['FLASK_ENV'] == 'development', then you only need to only set the FLASK_ENV environment variable in the PyCharm configuration for your app.
An entire script could look like this:
from os import environ as env, popen
import json
from flask import Flask
# Load env vars with Doppler if not already populated by checking if `DOPPLER_PROJECT` env var exists
if env.get('FLASK_ENV') == 'development' and not env.get('DOPPLER_PROJECT'):
print('[info]: Populating secrets into env vars with Doppler')
doppler_vars = json.loads(popen('doppler secrets download --no-file --format json').read())
for key, value in doppler_vars.items():
env[key] = value
app = Flask(__name__)
@app.route('/')
def hello():
return 'Flask using Doppler secrets'
if __name__ == '__main__':
app.run(host=env['HOSTNAME'], port=env['PORT'])
2. Use the patch-env Python package as a development dependency
If you didn’t want to leak Doppler implementation details into your app code, another option is to use the patch-env Python library.
You simply add a PATCH_ENV_COMMAND env var in PyCharm whose value is the command to return a list of environment variables that the library will use to populate os.environ prior to Python running your code.
I’m pleased to announce that we’ve released a doppler-env Python package to make it even easier to integrate Doppler into both PyCharm and Visual Studio code.
To use:
Install doppler-env in your local development environment:
pip install doppler-env
Define the DOPPLER_ENV environment variable in your IDE, editor, or terminal:
export DOPPLER_ENV=1
Run or debug your application in your IDE, editor, or terminal: