Skip to content

Project 4: Pull Live OPR & EPA Data with Python

learnfrc.com
learnfrc.comAuthor
Veer Bajaj
Veer BajajMaintainer

Hand scouting and public analytics are complementary: your data captures reliability and intent; OPR/EPA capture aggregate scoring across the whole event. This project pulls both with a few lines of Python.

OPR from The Blue Alliance. OPR (Offensive Power Rating) uses linear algebra to estimate each team’s average point contribution. TBA exposes it per-event. Get a free read API key from your TBA account page, then:

import requests
HEADERS = {"X-TBA-Auth-Key": "YOUR_TBA_READ_KEY"}
EVENT = "2026wabon" # event key: year + event code
oprs = requests.get(
f"https://www.thebluealliance.com/api/v3/event/{EVENT}/oprs",
headers=HEADERS
).json()
# oprs["oprs"] is {team_key: opr_value}, e.g. {"frc254": 78.3, ...}
for team, opr in sorted(oprs["oprs"].items(), key=lambda kv: -kv[1])[:8]:
print(team, round(opr, 1))

That prints the top eight teams by OPR — a fast first cut at “who scores a lot.” Remember OPR is a prediction, not ground truth; it can be distorted by who a team played with, so it supplements but never replaces real scouting.

EPA from Statbotics. EPA (Expected Points Added) is an Elo-derived model expressed in point units, and it separates into auto, teleop, and endgame component EPAs plus ranking-point EPAs — which map cleanly onto REBUILT’s phases. Statbotics offers a REST API and a Python package:

import statbotics
sb = statbotics.Statbotics()
row = sb.get_team_event(254, "2026wabon")
# row is a dict of EPA stats for that team at that event.
# Inspect the keys to find the component fields, then pull what you need:
print(row.keys())

The exact field names for the auto/teleop/endgame components are documented in the Statbotics REST/Python docs — print row.keys() once and read off the components, since the schema evolves between Statbotics versions. With those values you can ask sharper questions than “who’s good”: Which teams have highendgame EPA? (great TOWER climbers, relevant to the TRAVERSAL ranking point). Which teams have high auto EPA? (they help win the early HUB-active windows).

Merge with your scouting. Build a table keyed by team number with columns: your avg teleop fuel, your died count, TBA OPR, and the Statbotics auto/teleop/endgame EPA components. The magic is in the disagreements. A team with high OPR/EPA but a high died-count in your data is a reliability risk the public stats can’t see. A team with mediocre OPR but rock-solid reliability and a strong climb may be an underrated second-pick. Use the analytics to rank, then use your scouting to break ties and catch risks.

  • TBA’s /event/{key}/oprs endpoint returns per-team OPR keyed under an ‘oprs’ object; it predicts scoring but is sensitive to alliance partners.
  • Statbotics EPA is in point units and splits into auto/teleop/endgame components; print row.keys() to read the exact field names for your version.
  • The decisive insight comes from disagreements: high public rating + high died-count in your data = a hidden reliability risk.

This lesson was adapted from learnfrc.com.