Get Betting Odds with Raspberry PI and Odds-API (free)

0
(0)

Last Updated on 29th March 2024 by peppe8o

This tutorial will show you how to get betting odds with Raspberry PI by using Odds-API, a web service offering a way to download worldwide betting odds from multiple bookmakers from a Python script.

With my tutorial, you will be able to download odds for upcoming and live events, and you will get them into an Excel spreadsheet to make your analysis of that data.

About Odds-API

The Odds API is a web service offering betting odds available with easy-to-use web requests. This means that you can scrape their data from a request to their servers.

It offers Odds data of a wide list of bookmakers from the US, EU, UK, and AU. The full list of bookmakers is available at https://the-odds-api.com/sports-odds-data/bookmaker-apis.html, while the full list of sports is available at https://the-odds-api.com/sports-odds-data/sports-apis.html.

They also offer Excel plugins, but I usually prefer getting them into a Python script, so that I can arrange data according to my need and then output to an Excel file with a pre-made elaboration.

Odds API offers different pricing plans. They include a Free plan with 500/monthly requests and excluding historical data. Every script run can issue multiple requests (so, using multiple “credits”). The script from the following paragraphs, for example, will use 8 credits at each run, but you can reduce it by reducing the number of regions (as we’ll see later). Usually, that monthly request amount is already fitting the needs of many people.

For this project, I will use my Raspberry PI Zero 2 W computer board, but this should work on any Raspberry PI computer board.

What We Need

As usual, I suggest adding from now to your favourite e-commerce shopping cart all the needed hardware, so that at the end you will be able to evaluate overall costs and decide if to continue with the project or remove them from the shopping cart. So, hardware will be only:

raspberry-pi-zero-2-w-250px-image

Step-by-Step Procedure

Get an Odds API Token

Getting a free API token is simple. Just register with the free link (available at https://the-odds-api.com/#get-access). It requests your first name and email address (no password, no accounts, no data). You will get the free token in your email address.

Prepare the Operating System

Start preparing your OS. I will use a Raspberry PI OS Lite 64-bit, but you can also use the Raspberry PI OS Desktop, in this case working from its internal terminal.

With the Raspberry PI OS Lite, the Excel file will be produced and saved on its storage. So you will have to transfer it to your computer with a file transfer software (for example FileZilla) to open it with Excel or any spreadsheet editor supporting the XLSX format.

Make your OS up to date. From the terminal, please use the following command:

sudo apt update -y && sudo apt upgrade -y

I will use the Pandas library. You can install it with the following command:

sudo apt install python3-pandas -y

To export our data to Excel, we need to use pip3. The command will be the following:

sudo apt install python3-pip -y

We also need to create a new virtual environment and enter here. Please note that I named this environment as “my_project”, but you can give it your favourite name:

python3 -m venv --system-site-packages my_project
source ./my_project/bin/activate

You can check that you entered the new virtual environment as your shell will show you the environment name:

(my_project) pi@raspberrypi:~ $

Now, we can install the openpyxl, which will allow us to export data to the XLSX format:

 pip3 install openpyxl

Please remember that you will need to activate the virtual environment every time you will need to use the Odds API script. You can exit from the virtual environment by using the command “deactivate”.

Get my p8o-odds.py Python Script

You can now download my Python script to get betting odds on Raspberry PI with the following terminal command:

wget https://peppe8o.com/download/python/bet-odds/p8o-odds.py

The following paragraphs will explain the code line by line. Before moving to the next chapter, please remember to update the API_KEY as described below. You can edit the file with nano:

nano p8o-odds.py

At the beginning, we import the required libraries:

import argparse
import pandas as pd
import requests

Then we set the name for our XLSX output file. here you can use the name you prefer:

output_file = "output.xlsx"

The following rows will prepare the Python request string, according to the Odds API documentation:

parser = argparse.ArgumentParser(description='Sample V4')
parser.add_argument('--api-key', type=str, default='')
args = parser.parse_args()

In the following line, please set the API KEY with the one you received at the registration stage. The API_KEY must be included inside brackets:

API_KEY = '<<Your_API_Key_Here>>'

The following line enables you to choose which specific sports odds you want to get, by setting the sport key. You can see the list of available values at https://the-odds-api.com/sports-odds-data/sports-apis.html (“Sport Key” column). With the “upcoming” value you will get back the next 8 games across all sports:

SPORT = 'upcoming'

The following line allows you to filter specific regions. Available values are uk, us, us2, eu, and au. You can also set multiple regions, by adding them as comma delimited as in my script example. Please remember to avoid adding spaces between region codes!

REGIONS = 'us,us2,uk,eu'

The following line enables you to choose between different betting markets (h2h, spreads, and totals). More info is available at https://the-odds-api.com/sports-odds-data/betting-markets.html:

MARKETS = 'h2h,spreads'

Now, a few more settings follow: the ODDS_FORMAT (available values are “decimal” or “american”) and the DATE_FORMAT (values are “iso” or “unix”).

ODDS_FORMAT = 'decimal'
DATE_FORMAT = 'iso'

The following part will download a list of the in-season sports. To say the truth, you can even skip this part (by commenting it out by prepending the “#” character at the begin of the lines), it doesn’t consume your credits. I already commented out the “else” part as it was filling my terminal console by printing information not required to the script goal:

sports_response = requests.get('https://api.the-odds-api.com/v4/sports', params={
    'api_key': API_KEY
})

if sports_response.status_code != 200:
    print(f'Failed to get sports: status_code {sports_response.status_code}, response body {sports_response.text}')
#else:
#    print('List of in season sports:', sports_response.json())

The following line will submit the odds request, according to the Odds API docs:

odds_response = requests.get(f'https://api.the-odds-api.com/v4/sports/{SPORT}/odds', params={
    'api_key': API_KEY,
    'regions': REGIONS,
    'markets': MARKETS,
    'oddsFormat': ODDS_FORMAT,
    'dateFormat': DATE_FORMAT,
})

Then, an IF…ELSE statement follows. If the service answered with an error, the script will show you that error in your console. Otherwise, the “odds_json” variable will collect the query results and your terminal will print the number of events downloaded, the requests remaining in your subscription, and the requests used for the current month. From the official docs, there was a print part (commented out in this script) showing the results in a raw format. I commented it because we’ll get the data into a more practical spreadsheet:

if odds_response.status_code != 200:
    print(f'Failed to get odds: status_code {odds_response.status_code}, response body {odds_response.text}')

else:
    odds_json = odds_response.json()
    print('Number of events:', len(odds_json))
#    print(odds_json)
    print('Remaining requests', odds_response.headers['x-requests-remaining'])
    print('Used requests', odds_response.headers['x-requests-used'])

The following part of the script is where my project differs from the official docs. We’ll pass all the response to a DataFrame object:

df = pd.DataFrame(odds_json)

If you inspect it (for example in Thonny, but this task is not explained here), you will find that it is a json including nested list objects and dictionary objects. But I want to convert it to a flat table, to make it easy to export to a spreadsheet.

Next, we create an empty odds table including all the odds rows. These column names come from my inspection of the returned objects. If you use a different MARKET value you should test it and find if there are any additional columns:

odds_table=pd.DataFrame(columns=['id', 'sport_key', 'sport_title', 'commence_time', 'home_team', 'away_team', 'bkm_key', 'bkm_title', 'bkm_last_update', 'mkt_key', 'mkt_last_update', 'out_name', 'out_price', 'out_point'])

The following part iterates every odd row, exploding all the nested items:

# iter every odd 
for e_ind, event in df.iterrows():
    for bookmaker in event.bookmakers:
        for market in bookmaker['markets']:
            for outcome in market['outcomes']:

When the MARKETS is set to spreads, we have the “point” column which is not available on h2h markets. For this reason, we intercept these cases and put the “point” value to “N/A” with the following IF statement:

                if 'point' not in outcome.keys(): outcome['point'] = 'N/A'

At this point, we can create a new DataFrame with one line, including all the data for the specific odd. Please note here that the column names are the same as in the odds_table object:

                line=pd.DataFrame({\
                    'id': event.id, \
                    'sport_key': event.sport_key,\
                    'sport_title': event.sport_title,\
                    'commence_time': event.commence_time,\
                    'home_team': event.home_team,\
                    'away_team': event.away_team,\
                    'bkm_key': bookmaker['key'],\
                    'bkm_title': bookmaker['title'],\
                    'bkm_last_update': bookmaker['last_update'],\
                    'mkt_key': market['key'],\
                    'mkt_last_update': market['last_update'],\
                    'out_name': outcome['name'],\
                    'out_price': outcome['price'],\
                    'out_point': outcome['point']\
                    }, index=[0])

Then, we can concatenate the new line to the odds_table to append it:

                odds_table = pd.concat([odds_table,line])

Finally, we reset the odds_table index, so that it has progressive row (index) numbers and we export the DataFrame to our output file:

odds_table=odds_table.reset_index()
odds_table.to_excel(output_file)

If you have the p8o-odds.py file open in nano, please close and save it (CTRL + X, then Y and press RETURN).

Running the p8o-odds.py and getting Betting Odds in Raspberry PI

Now, we can finally test the script. From your terminal, please run it with the following command:

(my_project) pi@raspberrypi:~ $ python3 p8o-odds.py

It will give you a summary of the events number and the requests, as shown in code explanation:

(my_project) pi@raspberrypi:~ $ python3 p8o-odds.py
Number of events: 42
Remaining requests 382
Used requests 118

When the script ends (the terminal prompt comes back to you), you can see the generated file with the “ls” command:

(my_project) pi@raspberrypi:~ $ ls
my_project  output.xlsx  p8o-odds.py

Download it to your personal computer (having a spreadsheet program) or, if you have Raspberry PI OS Desktop, open it in spreadsheet application. You will find all the downloaded odd quotes available for your analysis, similarly to the following picture:

betting-odds-raspberry-pi-odds-api-spreadsheet-output

Odds API Documentation

For more details about Odds API, please refer to the Odds-API Documentation page.

Betting Disclaimer

Please note that this tutorial has NOT the purpose of inviting or suggesting you to bet. Betting involves risk. Gamble responsibly. Know your limits and only bet what you can afford to lose.

What’s Next

If you want to discover many other projects for your Raspberry PI, you can take a look at peppe8o Raspberry PI computer tutorials.

Enjoy!

How useful was this post?

Click on a star to rate it anonymously!

Average rating 0 / 5. Vote count: 0

No votes so far! Be the first to rate this post.

We are sorry that this post was not useful for you!

Let us improve this post!

Tell us how we can improve this post?