2
app = Flask(__name__)

app.config.update(
    MAIL_SERVER = 'smtp.gmail.com',
    MAIL_PORT = 465,
    MAIL_USE_SSL = True,
    MAIL_USE_TLS = False,
    MAIL_USERNAME = '******',
    MAIL_PASSWORD = '******'
)

mail = Mail(app)

#CS50.net
def lookup(symbol):
    """Look up quote for symbol."""

    # Contact API
    try:
        response = requests.get(f"https://api.iextrading.com/1.0/stock/{urllib.parse.quote_plus(symbol)}/quote")
        response.raise_for_status()
    except requests.RequestException:
        return None

    # Parse response
    try:
        quote = response.json()
        return {
            "name": quote["companyName"],
            "price": float(quote["latestPrice"]),
            "symbol": quote["symbol"]
        }
    except (KeyError, TypeError, ValueError):
        return None


@app.route('/')
def print_date_time():
    Symbol = "PG"
    Symbol = lookup(Symbol)
    msg = mail.send_message(
        'PG',
        sender='*****',
        recipients=['******'],
        body = "PG DROP BELOW 91 buy now"
    )





scheduler = BackgroundScheduler()
scheduler.add_job(func=print_date_time, trigger="interval", seconds=10)
scheduler.start()

# Shut down the scheduler when exiting the app
atexit.register(lambda: scheduler.shutdown())

I Create an app with Flask using Python that will send me a Gmail every 10 seconds if the condition is met. When I ran the the application I got this:

"RuntimeError: Working outside of application context.

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().  See the
documentation for more information. "

My thought is that the error was caused by my attempt to send a message through Gmail which is outside of the application context. Any ideas ?? THks

HUNG
  • 35
  • 1
  • 5

1 Answers1

5

Your function print_date_time is being executed through a new thread outside the app context and the Mail object need it. You should pass a param with the app object to your function (the decorator route is not necessary). The value of this param is current_app._get_current_object().

I have reimplemented your function print_date_time:

def print_date_time(app):
    with app.app_context():
        Symbol = "PG"
        Symbol = lookup(Symbol)
        msg = mail.send_message(
            'PG',
            sender='*****',
            recipients=['******'],
            body = "PG DROP BELOW 91 buy now"
        )
j2logo
  • 649
  • 4
  • 9
  • the call to `_get_current_object()` was what I was missing in my flask app, thanks! – Hans May 29 '20 at 16:59
  • What I needed was `app = Flask(__name__)` and `with app.app_context():` – baziorek Dec 28 '22 at 18:04
  • In this line: "scheduler.add_job(func=print_date_time, trigger="interval", seconds=10)" do you have to add the "app" parameter to the print_date_time function call? – Source Matters Mar 13 '23 at 18:30