{"id":19840937,"url":"https://github.com/torvaney/statsbombapi","last_synced_at":"2025-05-01T19:30:48.593Z","repository":{"id":45760046,"uuid":"251446981","full_name":"Torvaney/statsbombapi","owner":"Torvaney","description":"An extendable Statsbomb API wrapper for data-pipelines","archived":false,"fork":false,"pushed_at":"2022-03-31T18:50:16.000Z","size":74,"stargazers_count":50,"open_issues_count":3,"forks_count":9,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-06T17:11:18.687Z","etag":null,"topics":["dataclasses","football-data","statsbomb"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Torvaney.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-03-30T22:56:26.000Z","updated_at":"2025-03-17T20:02:11.000Z","dependencies_parsed_at":"2022-08-31T12:41:31.578Z","dependency_job_id":null,"html_url":"https://github.com/Torvaney/statsbombapi","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Torvaney%2Fstatsbombapi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Torvaney%2Fstatsbombapi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Torvaney%2Fstatsbombapi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Torvaney%2Fstatsbombapi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Torvaney","download_url":"https://codeload.github.com/Torvaney/statsbombapi/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251932592,"owners_count":21667175,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dataclasses","football-data","statsbomb"],"created_at":"2024-11-12T12:28:46.860Z","updated_at":"2025-05-01T19:30:48.194Z","avatar_url":"https://github.com/Torvaney.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# statsbombapi\n\nAPI wrapper and dataclasses for StatsBomb data\n\n## Installation\n\nTo get the latest version from GitHub:\n\n``` bash\npip install git+https://github.com/torvaney/statsbombapi.git\n```\n\n## Getting started\n\n``` python\n\u003e\u003e\u003e import statsbombapi\n\n# Connect to the Public Data Repo\n\u003e\u003e\u003e api = statsbombapi.StatsbombPublic()\nUserWarning: Please be responsible with StatsBomb data and make sure you have\n registered your details on https://www.statsbomb.com/resource-centre, and read and\n accepted the User Agreement (available on the same page).\n  warnings.warn(statsbomb_data_advice)\n\n# Or, if connecting to the API proper\n\u003e\u003e\u003e api = statsbombapi.StatsbombAPI(username='...', password='...')\n```\n\nThe StatsBomb API provides 4 routes, which can be accessed by calling the\ncorresponding methods on `StatsBombPublic` or `StatsBombAPI`.\n\n* competitions - `api.competitions()`\n* matches - `api.matches(competition_id, season_id)`\n* lineups - `api.lineups(match_id)`\n* events - `api.events(match_id)`\n\n### Competitions\n\n``` python\n\u003e\u003e\u003e competitions = api.competitions()\n\u003e\u003e\u003e competitions[0].competition\nCompetition(id=37, name=\"FA Women's Super League\", gender=\u003cGender.FEMALE: 'female'\u003e, country_name='England')\n\n\u003e\u003e\u003e competitions[0].season\nSeason(id=42, name='2019/2020')\n\n\u003e\u003e\u003e competitions[0].match_updated, competitions[0].match_available\n(datetime.datetime(2020, 3, 11, 14, 9, 41, 932138),\n datetime.datetime(2020, 3, 11, 14, 9, 41, 932138))\n\n\u003e\u003e\u003e # Or extract individual objects from the API response\n\u003e\u003e\u003e set(statsbombapi.extract(statsbombapi.Competition, competitions))\n{Competition(id=11, name='La Liga', gender=\u003cGender.MALE: 'male'\u003e, country_name='Spain'),\n Competition(id=37, name=\"FA Women's Super League\", gender=\u003cGender.FEMALE: 'female'\u003e, country_name='England'),\n Competition(id=43, name='FIFA World Cup', gender=\u003cGender.MALE: 'male'\u003e, country_name='International'),\n Competition(id=49, name='NWSL', gender=\u003cGender.FEMALE: 'female'\u003e, country_name='United States of America'),\n Competition(id=72, name=\"Women's World Cup\", gender=\u003cGender.FEMALE: 'female'\u003e, country_name='International')}\n\n\u003e\u003e\u003e set(statsbombapi.extract(statsbombapi.Season, competitions))\n{Season(id=1, name='2017/2018'),\n Season(id=2, name='2016/2017'),\n Season(id=21, name='2009/2010'),\n Season(id=22, name='2010/2011'),\n Season(id=23, name='2011/2012'),\n Season(id=24, name='2012/2013'),\n Season(id=25, name='2013/2014'),\n Season(id=26, name='2014/2015'),\n Season(id=27, name='2015/2016'),\n Season(id=3, name='2018'),\n Season(id=30, name='2019'),\n Season(id=37, name='2004/2005'),\n Season(id=38, name='2005/2006'),\n Season(id=39, name='2006/2007'),\n Season(id=4, name='2018/2019'),\n Season(id=40, name='2007/2008'),\n Season(id=41, name='2008/2009'),\n Season(id=42, name='2019/2020')}\n```\n\n### Matches\n\n``` python\n\u003e\u003e\u003e matches = api.matches(competition_id=37, season_id=42)\n\n\u003e\u003e\u003e # You can use the `extract` function to find items of any relevant type,\n\u003e\u003e\u003e # even if they are nested to arbitrary depth\n\u003e\u003e\u003e teams = set(statsbombapi.extract(statsbombapi.Team, matches))\n\u003e\u003e\u003e countries = set(statsbombapi.extract(statsbombapi.Country, matches))\n\u003e\u003e\u003e referees = set(statsbombapi.extract(statsbombapi.Referee, matches))\n```\n\n### Lineups\n\n``` python\n\u003e\u003e\u003e lineups = api.lineups(match_id=2275086)\n\n\u003e\u003e\u003e # Same as before...\n\u003e\u003e\u003e players = set(statsbombapi.extract(statsbombapi.Player, lineups))\n\u003e\u003e\u003e list(players)[0]\nPlayer(id=15616, name='Kim Little', birth_date=None, gender=None, height=None, weight=None,\n country=Country(id=201, name='Scotland'), nickname=None)\n```\n\n### Events\n\n``` python\n\u003e\u003e\u003e # Last, but certainly not least\n\u003e\u003e\u003e events = api.events(match_id=2275086)\n\u003e\u003e\u003e events[224]\nEvent(id=UUID('8b7f985e-2fa5-4b08-9893-0d1b77cf7076'), index=225, period=1,\n timestamp=datetime.time(0, 4, 35, 263000), minute=4, second=35,\n type=EventType(id=43, name='Carry'), possession=13,\n possession_team=Team(id=968, name='Arsenal WFC', gender=None, country=None),\n play_pattern=PlayPattern(id=4, name='From Throw In'),\n team=Team(id=968, name='Arsenal WFC', gender=None, country=None),\n duration=0.444403, related_events=[UUID('7eed3cb4-b02c-4ddb-bb98-1526cd4c89d5'), UUID('8af13ea5-1b32-4ea2-91fd-93756979744d')],\n location=[28.6, 20.8], under_pressure=None, off_camera=None, out=None,\n player=Player(id=10405, name='Lia Wälti', birth_date=None, gender=None, height=None, weight=None, country=None, nickname=None),\n position=Position(id=2, name='Right Back'), tactics=None, counterpress=None,\n fifty_fifty=None, bad_behaviour=None, ball_receipt=None, ball_recovery=None,\n block=None, carry=Carry(end_location=[28.6, 20.8]), clearance=None, dribble=None,\n dribbled_past=None, duel=None, foul_committed=None, foul_won=None, goalkeeper=None,\n half_end=None, half_start=None, injury_stoppage=None, interception=None,\n miscontrol=None, pass_=None, player_off=None, pressure=None, shot=None, substitution=None)\n```\n\n## Configuration and extensibility\n\nIf you don't want to use dataclasses, `statsbombapi` provides an extensible API client\nto enable you to fetch StatsBomb data in whatever format you want, from whichever\nsource you want.\n\n### Loaders and Decoders\n\nThe API Client is composed of a loader and a decoder:\n\n* The **loader** takes fetches StatsBomb data from some data source. For example,\n  the StatsBomb API, or the [StatsBomb Open Data repo](https://github.com/statsbomb/open-data/).\n* The **decoder** converts the statsbomb data into the desired format. For example, JSON, or dataclasses.\n\n```python\nclient = statsbombapi.StatsbombPublic()\n\n# Is equivalent to\nclient = statsbombapi.APIClient(\n  loader=statsbombapi.loaders.OpenDataLoader(),\n  decoder=statsbombapi.decoders.DataclassDecoder()\n)\n```\n\nAlternative decoders can be used to return data in a different format:\n\n```python\njson_client = statsbombapi.APIClient(\n  loader=statsbombapi.loaders.OpenDataLoader(),\n  decoder=statsbombapi.decoders.JsonDecoder()\n)\n\n# You can also supply the decoder to the pre-defined clients\njson_client = statsbombapi.StatsbombPublic(\n  decoder=statsbombapi.decoders.JsonDecoder()\n)\n\njson_client = statsbombapi.StatsbombAPI(\n  username='...',\n  password='...',\n  decoder=statsbombapi.decoders.JsonDecoder()\n)\n```\n\nYou can use this interface to use own custom decoders. For example,\nyou might want to return data as pandas DataFrames:\n\n```python\nimport pandas as pd\n\ndataframe_decoder = statsbombapi.decoders.CompositeDecoder(\n  # The default loader returns the object as bytes, so we need\n  # to chain together two decoders using `CompositeDecoder`.\n  # The first (`JsonDecoder`) uses json.decode to decode the API response into\n  # Python objects (lists and dicts)\n  statsbombapi.decoders.JsonDecoder(),\n  # The second uses the `pd.DataFrame` constructor on the output of 4 API routes\n  # (after they've been decoded by `JsonDecoder`)\n  statsbombapi.decoders.UniformDecoder(pd.DataFrame)\n)\n\ndf_client = statsbombapi.StatsbombPublic(\n  decoder=dataframe_decoder\n)\n\n\u003e\u003e\u003e print(df_client.events(match_id=2275086))\n                                        id  index  period     timestamp  minute  second  ...\n0     098da6e7-be60-4e70-8567-916873b0ba15      1       1  00:00:00.000       0       0  ...\n1     7ef1ced6-7044-4788-a7b7-d9d669071ecd      2       1  00:00:00.000       0       0  ...\n2     9e1da46b-dccc-4382-9603-d1fc1203b041      3       1  00:00:00.000       0       0  ...\n3     a5f24a50-053f-4c18-920d-5e70471e31c4      4       1  00:00:00.000       0       0  ...\n4     b3394890-ef26-4709-b00c-bcba2985a4cc      5       1  00:00:00.512       0       0  ...\n...                                    ...    ...     ...           ...     ...     ...  ...\n3260  0623b1ff-742e-4ee7-9c85-f27bee25c761   3261       2  00:49:32.803      94      32  ...\n3261  69ab6703-a024-44b9-9883-05b19586be86   3262       2  00:49:32.930      94      32  ...\n3262  34f79b82-e513-4ab5-9393-9f4e223f7ed4   3263       2  00:49:33.326      94      33  ...\n3263  a3907011-3386-4578-a910-51cfa5bb5773   3264       2  00:49:33.738      94      33  ...\n3264  70f30ecb-b85d-48d9-83bc-f62e1613dc3f   3265       2  00:49:33.738      94      33  ...\n```\n\nYou can use the `APIClient` class to configure the loader, too. For example, you\nmight want to load from disk (`statsbombapi.LocalLoader`). Or, you might\ndefine a custom loader to (for example) cache data locally, or pull data from s3.\n\n\n## Yet another statsbomb API package?!\n\nYes! `statsbombapi` aims to make it easier to extract and parse statsbomb\ndata with the use of dataclasses.\n\nThere are some great pre-existing packages for working with statsbomb data:\n\n* https://github.com/statsbomb/statsbombpy\n* https://github.com/imrankhan17/statsbomb-parser\n\nThese are primarily built around fetching StatsBomb data as dataframes.\nThis is great for interactive work (for example, in a jupyter notebook) and you\nshould definitely consider whether they match your use-case.\n\nHowever, I have found that this approach sometimes isn't ideal when developing data pipelines\nand doing ETL. By parsing data from the StatsBomb API into specific data structures,\nI hope that this package can make these situations easier.\n\n## Development\n\n### Testing\n\nRun tests with `pytest test`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftorvaney%2Fstatsbombapi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftorvaney%2Fstatsbombapi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftorvaney%2Fstatsbombapi/lists"}