Search code examples
pythonbottleyahoo-finance

How can I refresh data from yahoo finance API every time webpage is viewed in Python?


I'm running a website for personal use using Bottle, a simple web server for python.

I'm using this API to get market data from yahoo finance.

This is a simplified version of my script (my first script with Python, btw) with comments explaining how it works. I hope this is understandable: EDIT: Don't know if I made it clear but not all the code is here, I took a lot out because in this case it is irrelevant.

from bottle import route, run, template
from yahoo_finance import Share
#Using AAPL and FB as an example..
# Gets market data
AAPL = Share('AAPL')
FB = Share('FB')
# Does a whole bunch of things with the data that eventually makes readable portfolio percentages..
# This is SUPPOSED to be a function that refreshes the data so that when called in the template it has up to date data.
# Refresh market data..
def refreshAll():
    AAPL.refresh()
    FB.refresh()
    #Basically this just has a bunch of lines that refreshes the data for every symbol
# Makes it accessible to my template..
# Variables changed to make it understandable..
my_dict = {'holdings': printTotalHoldings, 'day_change': PercentDayChange, 'total_change': PercentTotalChange, 'date': date}
# This is supposed to make the function accessible by the view. So when I call it, it refreshes the data. Doesn't seem to work though..
my_dict['refresh'] = refreshAll

# Makes the template routed to root directory.
@route('/')
def index():
    # Template file index.tpl.. **my_dict makes my variables and functions work on the view.
    return template('index', **my_dict)
# Starts the webserver on port 8080
if __name__ == '__main__':
    port = int(os.environ.get('PORT', 8080))
    run(host='0.0.0.0', port=port, debug=True)

So that's basically what my index.py file looks like.

This is what I have in my template on the top of the page. I would think that each time the page is viewed it refreshes the data, right?

% refresh() #Refreshes market data

Then to call the variables with the data I just put something like this in place of where it should go in the HTML:

<p class="day_change">Today's Change: <span id="price">{{get('day_change')}}</span></p>

That all works fine except the data never changes. In order to actually refresh data I have to stop and start my script on the server. Does this make sense? So my question is, how can I get my data to refresh without stopping and restarting my script every time?

Thanks! Please let me know if something doesn't make enough sense. I've been having trouble with this for a bit.


Solution

  • If you're not in DEBUG mode, then Bottle is caching your rendered template.

    Couple of things:

    • Turn debug mode on and see if that helps. bottle.debug(True) before you run the server. (EDIT: I hadn't noticed earlier that you're already using debug mode. Leaving this item here anyway for reference.)

    • Do not call refresh() (or any other state-changing or blocking functions) from within your template. It's bad idea. As totowtwo suggested, you should call it from index before you invoke the template.


    @route('/')
    def index():
        refresh()
        return template('index', **my_dict)
    

    • Print out the value of AAPL et al. after you call refresh() but before you invoke the template, to confirm that they're being updated as you expect.

    @route('/')
    def index():
        refresh()
        # print the value of AAPL here, to confirm that it's updated
        return template('index', **my_dict)
    

    • How does your template have access to AAPL and FB, anyway? Where are they being passed?