Le code peut être installé et lancé avec un simple sbt run.
Le comportement attendu au premier lancement est le suivant :
/teams, puis /games, puis /stats.json (dans un répertoire ./local).json avec Spark.csv dans des sous-répertoires de ./output :
teams_games_df: "un DataFrame avec le nombre de points marqués par l'équipe, l'id du match, le nom et l'id de l'équipe"stats_by_game_and_team: "un DataFrame avec l'id du match, l'id de l'équipe, le nombre de points marqués (pts), le nombre de rebonds (reb), le nombre de passe décisive (ast) et le nombre de blocks (blk)."final_df: la fusion des 2 précédentsLors des lancements suivants, si les fichiers .json sont déjà présents, on ne va pas consulter l'API pour rien ; il faut plus d'une centaine de requêtes (!) pour récupérer toutes les données exigées et ça ne me semble pas correct de flooder de requêtes un service gratuit.
J'ai testé le projet avec un git clone tout frais du repo, et il est censé marcher. Au cas où, je laisse qd meme un répertoire expected qui montre (en version abregée) le contenu attendu des répertoires local et output après exécution.
J'ai essayé d'exploiter au maximum le système de types de Scala pour valider que les données récupérées par l'API sont au format attendu (voir le fichier src/main/scala/Games.scala).
Je n'ai pas réalisé la partie SQL ni laissé trop de commentaires dans le code car j'ai déjà passé vraiment BEAUCOUP de temps (de l'ordre de 3-4 jours de travail à temps complet) sur cet examen qui me semble très difficile. Je dois dire aussi que l'énoncé n'est pas forcément très clair..
Puisqu'il faut qd meme faire une bonne centaine de requêtes pour récupérer toutes les données, je n'ai pas ajouté de timer sur chaque requẽte. Mais du coup il est commun d'atteindre le rate-limit de l'API. Il est attendu de voir ce genre de trace à l'exécution :
ResponseMetadata(97,39,40,100,9665)
ResponseMetadata(97,40,41,100,9665)
ResponseMetadata(97,41,42,100,9665)
ResponseMetadata(97,42,43,100,9665)
ResponseMetadata(97,43,44,100,9665)
ResponseMetadata(97,44,45,100,9665)
ResponseMetadata(97,45,46,100,9665)
ResponseMetadata(97,46,47,100,9665)
Got 429 error, retrying after 1s
Don't panic, this should work again within 20s after the last successful request
...
Got 429 error, retrying after 1s
Don't panic, this should work again within 20s after the last successful request
ResponseMetadata(97,47,48,100,9665)
ResponseMetadata(97,48,49,100,9665)
ResponseMetadata(97,49,50,100,9665)
ResponseMetadata(97,50,51,100,9665)
ResponseMetadata(97,51,52,100,9665)
ResponseMetadata(97,52,53,100,9665)
ResponseMetadata(97,53,54,100,9665)
ResponseMetadata(97,54,55,100,9665)
ResponseMetadata(97,55,56,100,9665)
ResponseMetadata(97,56,57,100,9665)
Le serveur répond à nouveau normalement après une période de "bannissement" de 20-30s.
Enfin, pour info, pour les autres élèves, l'API fonctionne très bien avec le paramètre teams_ids[], mais il faut le repéter autant de fois qu'il y a de valeurs dans le tableau : par exemple https://www.balldontlie.io/api/v1/games?seasons[]=2021&team_ids[]=24&team_ids[]=22 (et non le plus naturel : https://www.balldontlie.io/api/v1/games?seasons[]=2021&team_ids[]=24,22). Idem pour game_ids[] sur l'endpoint /stats. Il faudrait donc corriger cette phrase du sujet qui induit vraiment en erreur : "l'API ne fonctionne pas correctement, vous ne pouvez pas utiliser le paramètre team_ids[], mais seasons[] fonctionne"