Forums

Why Environmental Variables Not Being Read ?

In my __init__.py file I'm pulling config depending on environment:

if os.environ.get('FLASK_ENV') == 'production':
    from project.config import ProductionConfig
    current_config = ProductionConfig
elif os.environ.get('FLASK_ENV') == 'staging':
    from project.config import StagingConfig
    current_config = StagingConfig

app.config.from_object(current_config)  # throws error "referenced before assignment"

running echo $FLASK_ENV is giving me staging so the variable is set yet my app crashes when used.

Is there something PA-specific I need to know about ?

Hi there. I don't think the error you see is related to environment variables. What I see in your error log (state from UTC 2021-03-17 15:50:26) is that you're calling a function create_app on the line 80 of the __init__ file which uses app variable in it's body (line 45). If you don't define that variable in the scope of this function or it's not available in the global scope, that is the error you should expect.

Hi pafk, thank you for taking a look. I admit it is little bit puzzling because the way I had it set up worked fine until now, then I changed code to pull config depending on environmental variable defined in .bashrc file.

import os
from logging import FileHandler
from flask import Flask, render_template
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager
from flask_migrate import Migrate
from flask_bcrypt import Bcrypt
from flask_mail import Mail
if os.environ.get('FLASK_ENV') == 'production':
    from project.config import ProductionConfig
    current_config = ProductionConfig
elif os.environ.get('FLASK_ENV') == 'staging':
    from project.config import StagingConfig
    current_config = StagingConfig



login_mgr = LoginManager()
migrate = Migrate()
bcrypt = Bcrypt()
db = SQLAlchemy()
migrate = Migrate()
mail = Mail()


def create_app(script_info=None):
    if os.environ.get('FLASK_ENV') == 'production':
        if not os.path.exists('/home/markalexa/blog/project/api/images'):
            os.mkdir('project/api/images')
            os.mkdir('project/api/images/post')
            os.mkdir('project/api/images/card')
        app = Flask(__name__, template_folder='/home/markalexa/blog/client/build', static_folder='/home/markalexa/blog/client/build/static')
        file_handler = FileHandler('/home/markalexa/blog/project/errorlog.txt')
    elif os.environ.get('FLASK_ENV') == 'staging':
        if not os.path.exists('/home/pyseostaging/staging/project/api/images'):
            os.mkdir('project/api/images')
            os.mkdir('project/api/images/post')
            os.mkdir('project/api/images/card')
        app = Flask(__name__, template_folder='/home/pyseostaging/staging/client/build', static_folder='/home/pyseostaging/staging/client/build/static')
        file_handler = FileHandler('/home/pyseostaging/staging/project/errorlog.txt')
    app.logger.addHandler(file_handler)
    app.config.from_object(current_config)
    db.init_app(app)
    bcrypt.init_app(app)
    migrate.init_app(app, db)
    if os.environ.get('FLASK_ENV') == 'development':
        toolbar.init_app(app)
    login_mgr.init_app(app)
    login_mgr.session_protection = "strong"
    from project.api.models import Commander, Users, Posts, Comments

    from project.api.blog import blog_blueprint
    from project.api.auth import auth_blueprint

    app.register_blueprint(blog_blueprint)
    app.register_blueprint(auth_blueprint)

    @app.errorhandler(404)
    def error_handler(e):
        return render_template('index.html')

    return app


app = create_app()

the above __init__ file worked just fine until I added ifs with os.environ.get() conditional statements.

running echo $FLASK_ENV gives me staging as expected but the script isn't taking it. Sorry I know this is rather Python logic issue than issue with PA per se.

Here is our help page on how to set environment variables in your web apps: https://help.pythonanywhere.com/pages/environment-variables-for-web-apps/

That helped a lot, glenn. Thank you !

.

import os
import smtplib

sms ="this is just a test message"

def sendemail(sms):
    print(sms)


MY_EMAIL = "bijuzapeye@gmail.com"
MY_PASSWORD = os.environ.get("OWN_PASSWORD")

print(MY_PASSWORD)


TO_EMAIL = ["bijumly@yahoo.com", "bijublr@gmail.com","bijublr@gmail.com"]

with smtplib.SMTP("smtp.gmail.com") as connection:
    connection.starttls()
    connection.login(user=MY_EMAIL, password=MY_PASSWORD)
    connection.sendmail(from_addr=MY_EMAIL,to_addrs=TO_EMAIL,msg=f"Subject: Weather Prediction \n\n {sms}")
sendemail(sms)

above python code print(MY_PASSWORD) as None, which means the environment password is not taking

Yes, that would suggest that you are not setting that environment variable in the environment.

Please suggest how to set up environment variables, I have done and it is visible when I type env in the console

.

PYTHONSTARTUP=/home/bijumly/.pythonstartup.py
VIRTUALENVWRAPPER_WORKON_CD=1
https_proxy=http://proxy.server:3128
PYTHONANYWHERE_SITE=www.pythonanywhere.com
WORKON_HOME=/home/bijumly/.virtualenvs
TERM=xterm-256color
USER=bijumly
VIRTUALENVWRAPPER_PROJECT_FILENAME=.project
SHLVL=1

http_proxy=http://proxy.server:3128
LC_CTYPE=en_US.utf-8
PATH=/home/bijumly/.local/bin:/usr/local/julia-1.6.1/bin:/usr/lib/postgresql/12/bin/:/home/bijumly/.local/bin:/usr/local/julia-1.6.1/bin:/
usr/lib/postgresql/12/bin/:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
VIRTUALENVWRAPPER_HOOK_DIR=/home/bijumly/.virtualenvs
OLDPWD=/home/bijumly
_=/usr/bin/env
12:53 ~ $

Here is the console, I set up `OWN_PASSWORD=

Have a look at this help page. Please don't paste your passwords into public forums! :)

Now the code is running when it runs from Console, but when I Schedule, the same console is not taking, throwing an error as the environment variable is not set .

make sure that you are loading your env variables in your code when you run your scheduled task.

see here , I am loading the variable in the code MY_PASSWORD = os.environ.get("OWN_PASSWORD") Do I need anything else?

How are you setting the environment variable? If you do something like this:

export OWN_PASSWORD=something

...in a console, then it will exist in that console only. If you want to set something up so that it is always available in all of your consoles, and also in scheduled tasks, then you'll need to add that export command to your .bashrc file.