How to Fetch Data From a REST API With Python and Flask
Building an stock quote application that uses an external API
Get the project source code below, and follow along with the lesson material.
Download Project Source CodeTo set up the project on your local machine, please follow the directions provided in the README.md
file. If you run into any issues with running the project source code, then feel free to reach out to the author in the course's Discord channel.
Tracking Stock Prices
You've now built your first Flask application! In this next section, we're going to build upon this to create a web application for more than just dice rolling which we will deploy to the internet. Over the next few chapters we are going to extend this application further to add more functionality and explore more parts of Flask.
What we're building
Some people like tracking the price of stocks, but if you go to many stock websites, there's a lot of clutter and the largest piece of information that people care about (the stock price) is not obvious. With our Python and Flask skills, we can make an application to solve that problem.
Setting up.
In our terminal, let's go back to our fullstack-flask folder and create a new folder for our app (which we can call stock-app
)
cd ~/fullstack-flask
mkdir stock-app
cd stock-app
Again, we're going to set up a virtual environment.
python3 -m venv env
source env/bin/activate
This time, to install Flask, we're going to create a file called requirements.txt where we list all of the dependencies of our project
touch requirements.txt
We're also going to use a Python library called requests
to interface with an external API to fetch the data we need about stocks.
Put these lines in your file requirements.txt
:
Flask
requests
Once we've set up this file, we can install the requirements using pip by running
pip install -r requirements.txt
Then we're going to create a server.py
to start out our Flask application.
touch server.py
code . # optional: to open the folder in VS Code
Within server.py, we're going to repeat the Flask imports to initialize our Flask application. This time in addition to importing Flask, we're going to import requests
, a Python library to make HTTP requests.
from flask import Flask
app = Flask(__name__)
We will also need a free API key from FinancialModelingPrep.com to get access to the raw data. You can register for your own API key for free at https://financialmodelingprep.com/developer/docs/.
warning
The free API provided by FinancialModelingPrep.com requires an API key for usage. When we pass the URL parameters of apikey=demo
, the API only works for Apple's stock.
This free API key will give you a certain amount of free requests everyday. When you get your own API key, you will need to change the usage of 'demo'
in our code to be your own API key. You don't have to register for one if you only want to use the price of AAPL, you can just use the demo
API key.
Thinking about our Flask Application design
When building Flask applications, it is helpful to think about the URL structure of your final product. For the first version of our stock ticker application, we might want two endpoints if our application was hosted at FlaskFinance.com.
If we hit the root page of the application (FlaskFinance.com), we would want to see the prices of our favorite stocks, and there might be another page to render just the price of a single stock (for example FlaskFinance.com/stocks/APPL or FlaskFinance.com/stocks/GOOG)
Once we have an idea for what the routes should look like, Flask makes it easy to define these. We'll dive deeper into routing in a later chapter. We've already seen an example for the decorator for the index page (@app.route('/')
) but to accept an arbitrary string like we would need to for FlaskFinance.com/stocks/AAPL, we can tell Flask to expect a parameter by @app.route('/stocks/<ticker>')
, and then Flask will pass in an argument into the function based on what followed the in the URL path. For FlaskFinance.com/stocks/AAPL
, the value of ticker
would be AAPL
.
Every route we define needs to point to a different function that will handle requests to that route. Let's create two routes in server.py
for this.
@app.route('/')
def home():
return "This is the home page. Try going to /stocks/AAPL"
@app.route('/stocks/<ticker>')
def stock(ticker):
return "This is the page for the {} ticker".format(ticker)
We can try this in our browser by launching the Flask development server and see what we get.
FLASK_ENV=development FLASK_APP=server flask run
Your terminal output should look something like this:
Once your server is running you can pull up a page at 127.0.0.1:5000/stocks/AAPL
Now, we should try to get the actual prices of stocks using the API.
Let's write a function to fetch data from the API endpoint. I've already written it out here, and you can use it.
def fetch_price(ticker):
data = requests.get('https://financialmodelingprep.com/api/v3/stock/real-time-price/{}'.format(ticker.upper()), params={'apikey': 'demo'}).json()
return data["price"]
What this does: Issues a HTTP request to an API provided by financialmodelingprep.com which returns the price of the stock as a JSON object. Our function returns the price as a numeric value.
Once we have that we can integrate the fetch_price
function into our stock
function.
@app.route('/stocks/<ticker>')
def stock(ticker):
stock_price = fetch_price(ticker)
return "The price of {} is {}".format(ticker, stock_price)
Now if launch our Flask server and navigate to 127.0.0.1:5000/stocks/AAPL
FLASK_ENV=development FLASK_APP=server flask run
We should see the actual price of AAPL
in our browser.
- |
Lesson Transcript
[00:00 - 00:07] Hey folks, welcome back. In this section, we're going to talk about building a larger flask application.
[00:08 - 00:24] Specifically, what we're going to work on is a minimalistic version of Google Finance. Initially, it's just going to tell us the stock price of a particular stock ticker, but we can also extend it to include more information like financial metrics here.
[00:25 - 00:31] Now, you might be wondering where are we getting this data? The answer is we're talking to a third-party API.
[00:32 - 00:44] To do that, we're going to use a Python library named request to make actual HTTP requests to a third-party endpoint, which we'll go over soon. To get started, let's go back in our terminal.
[00:45 - 00:53] We have our flask project folder, and within it, we have our existing flask application. Let's go ahead and make a new folder called stock app here.
[00:54 - 01:11] Once we're in it, we're going to have to set up a few things. The very first thing I do is I set up a virtual environment, and we have to activate our virtual environment.
[01:12 - 01:24] Here we see our virtual environment, and Python is all set up. The next thing we want to do is we actually want to specify the requirements of libraries we're going to be using.
[01:25 - 01:40] In this application, we're going to be using both flask as well as the request library. Instead of just running pip install flask and pip install requests, we're going to create a file to specify all of our requirements.
[01:41 - 01:57] It will very creatively be named requirements.txt, and in it, we're going to list flask and request. Then when we're back in our terminal, we're going to run pip install dash r requirements.txt.
[01:58 - 02:06] It's important that we're running this inside of our virtual environment. Otherwise, we'd be installing to our system default Python, which we probably don't want to do.
[02:07 - 02:16] All right, everything's installed. We can go back into VS code and actually build our server.
[02:17 - 02:20] The very first thing we're going to do is create a file. It was called server.py.
[02:21 - 02:26] We're going to put most of our logic here. We've already seen what it takes to build a flask application.
[02:27 - 02:45] We're going to run the standard from flask and port of flask, and then we're going to say app is equal to flask name, and there's your standard flask starter. We're going to have to write some code to fetch the data from our API.
[02:46 - 03:00] Let's take a quick look at our API and how that works. Here, I've pulled up the API we're using from financialmodinprep.com, and it basically just gives us an endpoint that gives us the price in JSON form.
[03:01 - 03:12] All we have to do is just change the ticker there. If you want to use this for stocks other than Apple, you're going to have to use a different API key, and you can register for a free API key on their website.
[03:13 - 03:20] For now, we're just going to be using Apple with the demo API key. We're going to have to write a function to actually get that data.
[03:21 - 03:27] Let's go ahead and do that in our editor. The very first thing we're going to want is we're going to need to specify the API URL.
[03:28 - 03:40] Here I've entered our API URL, and I've noticed that this is the thing that we 're going to change in each request. Next up, we're going to have to import the request library in order to actually make requests.
[03:41 - 04:00] Then we can write a function called fetch price that takes in a ticker and gets the data from the API. We're going to request.get and API URL, and we're going to format it so with ticker is going to be equal to the ticker that we're passed in here.
[04:01 - 04:07] Maybe we want to do params. We're going to pass in the API key.
[04:08 - 04:14] The API key is demo. Then we'll probably want the JSON data there.
[04:15 - 04:25] To be safe, let's go ahead and uppercase this string. I'll make sure we're in the right format at all times.
[04:26 - 04:33] At this point, data should be a dictionary that looks like this. We want to index into that price key.
[04:34 - 04:50] Data price is what we want to return. We can verify that this works by going back into our terminal and running what we just created in interactive mode.
[04:51 - 04:54] We wrote this function called fetch price. Let's fetch aAPL.
[04:55 - 04:58] Cool. It returns the right value.
[04:59 - 05:10] Going back here, let's go and write a flash function to... Or let's just write a function to start with that takes in a ticker and returns the string we want to return.
[05:11 - 05:28] Maybe we'll save the price as equal to fetch price of the ticker and we're going to return a string. The price of ticker is going to be the price.
[05:29 - 05:36] We're going to format that. What ticker is equal to ticker and price is equal to price.
[05:37 - 05:43] This is a function and the function seems like it'll work. We need a way to get it to be a URL.
[05:44 - 05:51] Our application is going to be hosted here localhost 5000 stock AAPL. How do we get the flash to render that?
[05:52 - 05:58] We've already seen this app.rud slash. That doesn't give us any ticker that we can pass in.
[05:59 - 06:09] The way we want to do that is we can specify an argument here. By specimen, this argument will pass whatever gets matched in this route to the first argument there.
[06:10 - 06:14] Now we want it to be stock slash ticker. Let's go ahead and do that.
[06:15 - 06:29] Just to be safe, let's add another route that says homepage. Try slash stock slash AAPL for now.
[06:30 - 06:35] We have a flash application. Now our job is to run it and test it out.
[06:36 - 06:48] Let's go back in our terminal and define our variables. We want to say flash gap is in server, maybe flask and is equal to development, then flask run.
[06:49 - 06:56] Okay, so our flask gap is running out. Let's go ahead and go to Firefox and let's go to localhost 5000.
[06:57 - 07:05] Localhost 5000. Okay, so it send us to that URL which told us we hit the wrong URL.
[07:06 - 07:13] So then let's go back here and it worked. So it said the price of Apple is $4,972.
[07:14 - 07:25] Now I can try some other stocks but our API key is invalid for those so we can 't do that. If we had a valid API key, it would have worked.
[07:26 - 07:41] So hopefully we now have a flask app that we can work with and you were able to get to this point. If you have any questions for a food, leave them in the form.
[07:42 - 07:52] But if not, over the next few videos, we're going to be enhancing the core of this application to first off look a little better but also to have a little more functionality as well.