Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
# impectPy 2.5.1

## Minor Changes
* fix bugs in the following functions that occured if either the coaches endpoint returned no coaches or the coaches endpoint being blacklisted for the user:
* `getEvents()`
* `getPlayerMatchSums()`
* `getSquadMatchSums()`
* `getPlayerMatchScores()`
* `getSquadMatchScores()`

# impectPy 2.5.0

## Major Changes
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

A package provided by: Impect GmbH

Version: v2.5.0
Version: v2.5.1

**Updated: October 15th 2025**
**Updated: October 17th 2025**

---

Expand Down Expand Up @@ -35,7 +35,7 @@ pip install impectPy
You can also install it from [GitHub](https://github.com/) with:

```cmd
pip install git+https://github.com/ImpectAPI/impectPy.git@v2.5.0
pip install git+https://github.com/ImpectAPI/impectPy.git@v2.5.1
```

## Usage
Expand Down
2 changes: 1 addition & 1 deletion impectPy/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# define version attribute
__version__ = "2.5.0"
__version__ = "2.5.1"

# import modules
from .access_token import getAccessToken
Expand Down
61 changes: 37 additions & 24 deletions impectPy/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
import numpy as np
import pandas as pd
import requests
from impectPy.helpers import RateLimitedAPI
import re
from impectPy.helpers import RateLimitedAPI, ForbiddenError
from .matches import getMatchesFromHost
from .iterations import getIterationsFromHost
import re

######
#
Expand Down Expand Up @@ -119,16 +119,23 @@ def getEventsFromHost(
ignore_index=True)[["id", "name"]].drop_duplicates()

# get coaches
coaches = pd.concat(
map(lambda iteration: connection.make_api_request_limited(
url=f"{host}/v5/customerapi/iterations/{iteration}/coaches",
method="GET"
).process_response(
endpoint="Coaches",
raise_exception=False
),
iterations),
ignore_index=True)[["id", "name"]].drop_duplicates()
coaches_blacklisted = False
try:
coaches = pd.concat(
map(lambda iteration: connection.make_api_request_limited(
url=f"{host}/v5/customerapi/iterations/{iteration}/coaches",
method="GET"
).process_response(
endpoint="Coaches",
raise_exception=False
),
iterations),
ignore_index=True)[["id", "name"]].drop_duplicates()
except KeyError:
# no coaches found, create empty df
coaches = pd.DataFrame(columns=["id", "name"])
except ForbiddenError:
coaches_blacklisted = True

# get matches
matchplan = pd.concat(
Expand Down Expand Up @@ -265,18 +272,6 @@ def getEventsFromHost(
right_on="id",
how="left",
suffixes=("", "_right")
).merge(
coaches[["id", "name"]].rename(columns={"id": "homeCoachId", "name": "homeCoachName"}),
left_on="homeSquadCoachId",
right_on="homeCoachId",
how="left",
suffixes=("", "_right")
).merge(
coaches[["id", "name"]].rename(columns={"id": "awayCoachId", "name": "awayCoachName"}),
left_on="awaySquadCoachId",
right_on="awayCoachId",
how="left",
suffixes=("", "_right")
).merge(
iterations,
left_on="iterationId",
Expand All @@ -285,6 +280,21 @@ def getEventsFromHost(
suffixes=("", "_right")
)

if not coaches_blacklisted:
events = events.merge(
coaches[["id", "name"]].rename(columns={"id": "homeCoachId", "name": "homeCoachName"}),
left_on="homeSquadCoachId",
right_on="homeCoachId",
how="left",
suffixes=("", "_right")
).merge(
coaches[["id", "name"]].rename(columns={"id": "awayCoachId", "name": "awayCoachName"}),
left_on="awaySquadCoachId",
right_on="awayCoachId",
how="left",
suffixes=("", "_right")
)

if include_kpis:
# unnest scorings and full join with kpi list to ensure all kpis are present
scorings = scorings.merge(kpis, left_on="kpiId", right_on="id", how="outer") \
Expand Down Expand Up @@ -532,6 +542,9 @@ def getEventsFromHost(
# add kpis
order = order + kpi_cols

if coaches_blacklisted:
order = [col for col in order if col not in ["homeCoachId", "homeCoachName", "awayCoachId", "awayCoachName"]]

# reorder data
events = events[order]

Expand Down
13 changes: 9 additions & 4 deletions impectPy/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@
######


class ForbiddenError(Exception):
"""Raised when the API returns a 403 Forbidden response."""
pass


class RateLimitedAPI:
def __init__(self, session: Optional[requests.Session] = None):
"""
Expand Down Expand Up @@ -115,10 +120,10 @@ def make_api_request(
f"Request-ID: {response.headers['x-request-id']} "
f"(Make sure to include this in any support request.)")
elif response.status_code == 403:
raise Exception(f"Received status code {response.status_code} "
f"(You do not have access to this resource.)\n"
f"Request-ID: {response.headers['x-request-id']} "
f"(Make sure to include this in any support request.)")
raise ForbiddenError(f"Received status code {response.status_code} "
f"(You do not have access to this resource.)\n"
f"Request-ID: {response.headers['x-request-id']} "
f"(Make sure to include this in any support request.)")
# check status code and terminate if other error
else:
raise Exception(f"Received status code {response.status_code} "
Expand Down
102 changes: 65 additions & 37 deletions impectPy/matchsums.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# load packages
import pandas as pd
import requests
from impectPy.helpers import RateLimitedAPI, unnest_mappings_df
from impectPy.helpers import RateLimitedAPI, unnest_mappings_df, ForbiddenError
from .matches import getMatchesFromHost
from .iterations import getIterationsFromHost

Expand Down Expand Up @@ -102,16 +102,23 @@ def getPlayerMatchsumsFromHost(matches: list, connection: RateLimitedAPI, host:
ignore_index=True)[["id", "name"]].drop_duplicates()

# get coaches
coaches = pd.concat(
map(lambda iteration: connection.make_api_request_limited(
url=f"{host}/v5/customerapi/iterations/{iteration}/coaches",
method="GET"
).process_response(
endpoint="Coaches",
raise_exception=False
),
iterations),
ignore_index=True)[["id", "name"]].drop_duplicates()
coaches_blacklisted = False
try:
coaches = pd.concat(
map(lambda iteration: connection.make_api_request_limited(
url=f"{host}/v5/customerapi/iterations/{iteration}/coaches",
method="GET"
).process_response(
endpoint="Coaches",
raise_exception=False
),
iterations),
ignore_index=True)[["id", "name"]].drop_duplicates()
except KeyError:
# no coaches found, create empty df
coaches = pd.DataFrame(columns=["id", "name"])
except ForbiddenError:
coaches_blacklisted = True

# get kpis
kpis = connection.make_api_request_limited(
Expand Down Expand Up @@ -248,14 +255,6 @@ def getPlayerMatchsumsFromHost(matches: list, connection: RateLimitedAPI, host:
right_on="id",
how="left",
suffixes=("", "_right")
).merge(
coaches[["id", "name"]].rename(
columns={"id": "coachId", "name": "coachName"}
),
left_on="coachId",
right_on="coachId",
how="left",
suffixes=("", "_right")
).merge(
countries.rename(columns={"fifaName": "playerCountry"}),
left_on="countryId",
Expand All @@ -264,6 +263,17 @@ def getPlayerMatchsumsFromHost(matches: list, connection: RateLimitedAPI, host:
suffixes=("", "_right")
)

if not coaches_blacklisted:
matchsums = matchsums.merge(
coaches[["id", "name"]].rename(
columns={"id": "coachId", "name": "coachName"}
),
left_on="coachId",
right_on="coachId",
how="left",
suffixes=("", "_right")
)

# rename some columns
matchsums = matchsums.rename(columns={
"scheduledDate": "dateTime",
Expand Down Expand Up @@ -304,6 +314,10 @@ def getPlayerMatchsumsFromHost(matches: list, connection: RateLimitedAPI, host:
# add kpiNames to order
order += kpis['name'].to_list()

# check if coaches are blacklisted
if coaches_blacklisted:
order = [col for col in order if col not in ["coachId", "coachName"]]

# select columns
matchsums = matchsums[order]

Expand Down Expand Up @@ -395,16 +409,23 @@ def getSquadMatchsumsFromHost(matches: list, connection: RateLimitedAPI, host: s
ignore_index=True)[["id", "name", "idMappings"]]

# get coaches
coaches = pd.concat(
map(lambda iteration: connection.make_api_request_limited(
url=f"{host}/v5/customerapi/iterations/{iteration}/coaches",
method="GET"
).process_response(
endpoint="Coaches",
raise_exception=False
),
iterations),
ignore_index=True)[["id", "name"]].drop_duplicates()
coaches_blacklisted = False
try:
coaches = pd.concat(
map(lambda iteration: connection.make_api_request_limited(
url=f"{host}/v5/customerapi/iterations/{iteration}/coaches",
method="GET"
).process_response(
endpoint="Coaches",
raise_exception=False
),
iterations),
ignore_index=True)[["id", "name"]].drop_duplicates()
except KeyError:
# no coaches found, create empty df
coaches = pd.DataFrame(columns=["id", "name"])
except ForbiddenError:
coaches_blacklisted = True

# unnest mappings
squads = unnest_mappings_df(squads, "idMappings").drop(["idMappings"], axis=1).drop_duplicates()
Expand Down Expand Up @@ -502,16 +523,19 @@ def getSquadMatchsumsFromHost(matches: list, connection: RateLimitedAPI, host: s
right_on="squadId",
how="left",
suffixes=("", "_home")
).merge(
coaches[["id", "name"]].rename(
columns={"id": "coachId", "name": "coachName"}
),
left_on="coachId",
right_on="coachId",
how="left",
suffixes=("", "_right")
)

if not coaches_blacklisted:
matchsums = matchsums.merge(
coaches[["id", "name"]].rename(
columns={"id": "coachId", "name": "coachName"}
),
left_on="coachId",
right_on="coachId",
how="left",
suffixes=("", "_right")
)

# rename some columns
matchsums = matchsums.rename(columns={
"scheduledDate": "dateTime"
Expand Down Expand Up @@ -549,6 +573,10 @@ def getSquadMatchsumsFromHost(matches: list, connection: RateLimitedAPI, host: s
# reset index
matchsums = matchsums.reset_index()

# check if coaches are blacklisted
if coaches_blacklisted:
order = [col for col in order if col not in ["coachId", "coachName"]]

# select & order columns
matchsums = matchsums[order]

Expand Down
Loading