Python
Requirements and suggested libraries to connect to the Live Data API using Python:
- Python 3.6 or greater and pip package installer
- graphql-python/gql - version v3.0.0a5
Check the installed version of gql with: pip show gql
All example queries were built in Apollo Studio and copied over. If your query has parameters make sure you copy over the variables JSON/Dict from Apollo as well. Note that your token expires after 24 hours.
Example - Retrieving Matches
A query to return the available matches within a given date.
from gql import gql, Client
from gql.transport.requests import RequestsHTTPTransport
# Add your credentials to the headers. We advise that you set your token as an environment variable and import it instead of hard coding it into the dict below.
reqHeaders = {
'Authorization': 'Bearer ' + "<YOUR_TOKEN>"
}
# Select your transport with a defined url endpoint
transport = RequestsHTTPTransport(
url="https://live-api.statsbomb.com/v1/graphql", headers=reqHeaders
)
# Create a GraphQL client using the defined transport
client = Client(transport=transport, fetch_schema_from_transport=True)
# Provide a GraphQL query
query = gql(
"""
query Live_match($where: live_match_bool_exp) {
live_match(where: $where) {
competition_id
match_away_score
match_away_team_name
match_date
match_home_score
match_home_team_name
match_id
match_name
season_id
}
}
"""
)
params = {
"where": {
"match_date": {
"_gt": "2022-09-01",
"_lt": "2022-11-01"
}
}
}
# Execute the query on the transport
result = client.execute(query, variable_values=params)
print(result)
{
"live_match": [
{
"competition_id": 44,
"match_away_score": None,
"match_away_team_name": "Charlotte",
"match_date": "2022-10-09",
"match_home_score": None,
"match_home_team_name": "New York Red Bulls",
"match_id": 1077782,
"match_name": "2022-10-09 New York RB vs. Charlotte",
"match_play_status": "Normal",
"season_id": 106,
},
{
"competition_id": 44,
"match_away_score": None,
"match_away_team_name": "DC United",
"match_date": "2022-10-01",
"match_home_score": None,
"match_home_team_name": "CF Montreal",
"match_id": 1077762,
"match_name": "2022-10-02 Montréal vs. D.C. United",
"match_play_status": "Normal",
"season_id": 106,
},
]
}
Retrieving event data
Query or subscribe to all events in a particular match.
from gql import gql, Client
from gql.transport.requests import RequestsHTTPTransport
reqHeaders = {
'Authorization': 'Bearer ' + "<YOUR_TOKEN>"
}
transport = RequestsHTTPTransport(url="https://live-api.statsbomb.com/v1/graphql",
headers=reqHeaders)
client = Client(transport=transport, fetch_schema_from_transport=True)
query = gql(
"""
query Live_match_event($where: live_match_event_bool_exp) {
live_match_event(where: $where) {
advantage
aerial_won
assist
backheel
body_part
card
competition_id
created_at
defensive
deflection
distance_to_opponents_goal
distance_to_own_goal
duration
end_x
end_y
end_z
finished
first_time
formation
freeze_frame
from_corner
from_free_kick
from_open_play
from_penalty_box
from_set_piece
from_six_yard_box
from_throw_in
goal_against
goal_for
height
id
in_attacking_half
in_defensive_half
in_defensive_third
in_final_third
in_penalty_box
in_six_yard_box
index
inside_attacking_half
inside_defensive_half
inside_defensive_third
inside_final_third
inside_penalty_box
inside_six_yard_box
into_attacking_half
into_defensive_half
into_defensive_third
into_final_third
into_penalty_box
into_six_yard_box
key_pass
lineup
match_id
minute
name
next_period
no_touch
nutmeg
off_camera
offensive
opposition_id
outcome
overrun
penalty
period
player_id
position
recipient_id
recovery_failure
replacement_id
save_block
season_id
second
start_x
start_y
start_z
status
team_id
technique
timestamp
type
updated_at
xg
}
}
"""
)
params = {
"where": {
"match_id": {
"_eq": 1099777
}
}
}
result = client.execute(query, variable_values=params)
print(result)
{
"data": {
"live_match_event": [
{
"advantage": null,
"aerial_won": null,
"assist": null,
"backheel": null,
"body_part": null,
"card": null,
"competition_id": 2,
"created_at": "2022-11-12T19:51:24.97",
"defensive": null,
"deflection": null,
"distance_to_opponents_goal": 74.11477,
"distance_to_own_goal": 61.652245,
"duration": null,
"end_x": null,
"end_y": null,
"end_z": null,
"finished": true,
"first_time": null,
"formation": null,
"freeze_frame": null,
"from_corner": null,
"from_free_kick": null,
"from_open_play": null,
"from_penalty_box": false,
"from_set_piece": null,
"from_six_yard_box": false,
"from_throw_in": null,
"goal_against": null,
"goal_for": null,
"height": null,
"id": "d2c6ceee-9ec5-4b0c-b215-a8e66517f76d",
"in_attacking_half": false,
"in_defensive_half": true,
"in_defensive_third": false,
"in_final_third": false,
"in_penalty_box": false,
"in_six_yard_box": false,
"index": 55,
"inside_attacking_half": null,
"inside_defensive_half": null,
"inside_defensive_third": null,
"inside_final_third": null,
"inside_penalty_box": null,
"inside_six_yard_box": null,
"into_attacking_half": null,
"into_defensive_half": null,
"into_defensive_third": null,
"into_final_third": null,
"into_penalty_box": null,
"into_six_yard_box": null,
"key_pass": null,
"lineup": null,
"match_id": 1099777,
"minute": 3,
"name": "ball-receipt",
"next_period": null,
"no_touch": null,
"nutmeg": null,
"off_camera": false,
"offensive": null,
"opposition_id": 21,
"outcome": "complete",
"overrun": null,
"penalty": null,
"period": 1,
"player_id": 11387,
"position": null,
"recipient_id": null,
"recovery_failure": null,
"replacement_id": null,
"save_block": null,
"season_id": 235,
"second": 44,
"start_x": 52.95,
"start_y": 75.58,
"start_z": null,
"status": "COMPLETE",
"team_id": 47,
"technique": null,
"timestamp": "00:03:44.417",
"type": null,
"updated_at": "2022-11-12T19:52:17.068439",
"xg": null
},
]
}
}
Subscribe to match events data
Subscribe to match events for a particular match. This query returns the last 5 events in the game, the example only includes a small subset of event columns, you can of course add more to fit your needs. Once the subscription is live, the last 5 events should be returned every time a new event comes in.
The following code will run in the terminal but not in an IPython kernel. If you're using IPython/Jupyter jump to the next example.
from gql import gql, Client
from gql.transport.websockets import WebsocketsTransport
import pprint
reqHeaders = {
'Authorization': 'Bearer ' + "<YOUR_TOKEN>"
}
ws_transport = WebsocketsTransport(url='wss://live-api.statsbomb.com/v1/graphql', headers=reqHeaders)
ws_client = Client(
transport=ws_transport,
fetch_schema_from_transport=True,
)
query = gql(
"""
subscription Live_match_event($where: live_match_event_bool_exp, $orderBy: [live_match_event_order_by!], $limit: Int) {
live_match_event(where: $where, order_by: $orderBy, limit: $limit) {
id
name
timestamp
team_id
player_id
start_x
start_y
}
}
"""
)
params = {
"where": {
"match_id": {
"_eq": 1099777
}
},
"orderBy": [
{
"timestamp": "desc"
}
],
"limit": 5
}
for result in ws_client.subscribe(query, variable_values=params):
pprint.pprint(result)
{
"live_match_event": [
{
"id": "ccb0937a-c139-417f-93c7-90f95d6c1c77",
"name": "match-status",
"player_id": None,
"start_x": None,
"start_y": None,
"team_id": 47,
"timestamp": "00:49:19.501",
},
{
"id": "fae1dff4-62dc-454d-b7b1-97f5127b40b3",
"name": "match-status",
"player_id": None,
"start_x": None,
"start_y": None,
"team_id": 47,
"timestamp": "00:49:19.101",
},
{
"id": "ce3c77de-fc89-4046-8dd3-6809621fc9de",
"name": "half-end",
"player_id": None,
"start_x": None,
"start_y": None,
"team_id": 47,
"timestamp": "00:49:17.108",
},
{
"id": "c4ab5884-f923-48ec-a967-832aec6cf3d4",
"name": "ball-receipt",
"player_id": 11387,
"start_x": 43.5,
"start_y": 45.5,
"team_id": 47,
"timestamp": "00:49:14.935",
},
{
"id": "ee4a6df4-c852-4547-a958-3854e708fa78",
"name": "pass",
"player_id": 80396,
"start_x": 34.2,
"start_y": 54.04,
"team_id": 47,
"timestamp": "00:49:13.833",
},
]
}
IPython/Jupyter
from gql import gql, Client
from gql.transport.websockets import WebsocketsTransport
import pandas as pd
async def main():
reqHeaders = {
'Authorization': 'Bearer ' + "<YOUR_TOKEN>"
}
ws_transport = WebsocketsTransport(url='wss://live-api.statsbomb.com/v1/graphql', headers=reqHeaders)
# Using `async with` on the client will start a connection on the transport
# and provide a `session` variable to execute queries on this connection
async with Client(
transport=ws_transport, fetch_schema_from_transport=True,
) as session:
# Execute single query
query = gql(
"""
subscription Live_match_event($where: live_match_event_bool_exp, $orderBy: [live_match_event_order_by!], $limit: Int) {
live_match_event(where: $where, order_by: $orderBy, limit: $limit) {
id
name
timestamp
team_id
player_id
start_x
start_y
}
}
"""
)
params = {
"where": {
"match_id": {
"_eq": 1099777
}
},
"orderBy": [
{
"timestamp": "desc"
}
],
"limit": 5
}
result = await session.execute(query, variable_values=params)
result = pd.DataFrame(result)
result = pd.json_normalize(result.live_match_event)
print(result)
await main()
id name timestamp team_id \
0 ccb0937a-c139-417f-93c7-90f95d6c1c77 match-status 00:49:19.501 47
1 fae1dff4-62dc-454d-b7b1-97f5127b40b3 match-status 00:49:19.101 47
2 ce3c77de-fc89-4046-8dd3-6809621fc9de half-end 00:49:17.108 47
3 c4ab5884-f923-48ec-a967-832aec6cf3d4 ball-receipt 00:49:14.935 47
4 ee4a6df4-c852-4547-a958-3854e708fa78 pass 00:49:13.833 47
player_id start_x start_y
0 NaN NaN NaN
1 NaN NaN NaN
2 NaN NaN NaN
3 11387.0 43.5 45.50
4 80396.0 34.2 54.04