nba_api icon indicating copy to clipboard operation
nba_api copied to clipboard

Get endpoints from angular

Open easis opened this issue 5 years ago • 8 comments

Hi, I'm developing my own stats NBA library (in C#, private repo atm sorry) and found a way to get (I think) all endpoints directly from the browsers console.

imagen

Just paste this little code to the developer console (F12 in firefox):

angular.module('nba-ng-hana-services')['_invokeQueue'].forEach((i) => {
	if(!i) return;
	
	let serviceType = i[1];
	if(serviceType !== 'service') return;
	
	let service = i[2];
	let serviceName = (service[0]).replace('Service', '');

	let params = service[1];
	if(params.length != 2) return;
	
	let endpointObj = params[1]();
	
	let endpoints = endpointObj['endpoints'];
	if(endpoints && endpoints.length > 0) {
		endpoints.forEach(subEndpoint => {
			let subEndpointName = subEndpoint['endpoint'];
			console.log('Service: ' + serviceName + ', Endpoint: ' + subEndpointName);
		});
	}
	
	let endpoint = endpointObj['endpoint'];
	
	console.log('Endpoint: ' + serviceName + ', Resource: ' + endpoint);
});

I'm not very proficient with js so I'm sure this can be shortened.

Also, you can get some constant definitions:

angular.module('stats')['_invokeQueue'][0][2][1]

imagen

easis avatar Jul 17 '20 18:07 easis

@easis - I'm unfamiliar with Angular. I installed Node and then Angular. I attempted to run your example, but just get ReferenceError: angular is not defined

rsforbes avatar Aug 09 '20 17:08 rsforbes

@rsforbes Sorry if I've been unclear. This should be executed in browser's console (F12 in firefox): imagen

EDIT: You also can right click the return of the call and copy the object (as a json). I'm working with an offline copy of these objects to automatically parse and generate C# classes: imagen imagen

easis avatar Aug 15 '20 15:08 easis

Hi, I'm developing my own stats NBA library (in C#, private repo atm sorry) and found a way to get (I think) all endpoints directly from the browsers console.

imagen

Just paste this little code to the developer console (F12 in firefox):

angular.module('nba-ng-hana-services')['_invokeQueue'].forEach((i) => {
	if(!i) return;
	
	let serviceType = i[1];
	if(serviceType !== 'service') return;
	
	let service = i[2];
	let serviceName = (service[0]).replace('Service', '');

	let params = service[1];
	if(params.length != 2) return;
	
	let endpointObj = params[1]();
	
	let endpoints = endpointObj['endpoints'];
	if(endpoints && endpoints.length > 0) {
		endpoints.forEach(subEndpoint => {
			let subEndpointName = subEndpoint['endpoint'];
			console.log('Service: ' + serviceName + ', Endpoint: ' + subEndpointName);
		});
	}
	
	let endpoint = endpointObj['endpoint'];
	
	console.log('Endpoint: ' + serviceName + ', Resource: ' + endpoint);
});

I'm not very proficient with js so I'm sure this can be shortened.

Also, you can get some constant definitions:

angular.module('stats')['_invokeQueue'][0][2][1]

imagen

Note: I'm NOT a JavaScript developer. So apologize if the terminology is not on point...

So I added a function that would console.save() after each loop using:

console.save(angular.module('stats')['_invokeQueue'][0][2][1], "my_object.json"); and this works for some endpoint objects, but not others.

Screen Shot 2020-08-15 at 1 15 16 PM

But even so, all the values are the same -- not the ACTUAL values for EACH endpoint. It's I think for one of the, but not sure which at this point and it's just output with the new name for the "forEach" loop I have, but again, ONLY for those first 10 endpoints...

e.g.

 let endpoints = endpointObj['endpoints'];
  if (endpoints && endpoints.length > 0) {
    endpoints.forEach((subEndpoint) => {
      let subEndpointName = subEndpoint['endpoint'];
      console.log('Service: ' + serviceName + ', Endpoint: ' + subEndpointName);
      console.log('------ inner loop: endpointObj:');
      console.log(Object.values(endpointObj));
      console.log(angular.module('stats')['_invokeQueue'][0][2][1]);
      console.log('------ endpointObj end ------ ');
    });

I can't seem to access the attributes or keys that would give the equivalent of that

angular.module('stats')['_invokeQueue'][0][2][1] values (a JSON object) for each endpoint.

The values seem to be hidden in the [[Scope] such as [['Scope']][2]['Stats']['_invokeQueue'][0][2][1] or [['Scope']][2]['obj'] if they were callable in the same manner.

But while the 'stats' part is accessible, the 'obj' isn't for some reason.

Screen Shot 2020-08-15 at 1 13 49 PM

pauldevos avatar Aug 15 '20 18:08 pauldevos

@pauldevos didn't know console.save() existed lol I'm not a JS developer neither so I can't help in some points. angular.module(string) expects a module name. Those modules can be found in this file: https://stats.nba.com/scripts/theme.min.js You can dowload it and beautify or load in the debugger of firefox (and clicking the curly braces button at bottom): imagen imagen

And then search for angular.module: imagen

Those modules contains services (constants and endpoints among other resources) accessibles from angular.module(module name)['_invokeQueue']. For example, calling angular.module('nba-ng-hana-services')['_invokeQueue'] will return an array with 125 items, each item is another array where first element is the string $provide, the second is the string service and the third element is another array whose first element is the name of the service (the endpoint name in this case) and the second one are the parameters.

easis avatar Aug 15 '20 20:08 easis

This looks very nice!

I was able to get all of them into a nice list.

alltimeleadersgrids
assistleaders
2assisttracker
boxscoreadvancedv2
boxscoredefensive
infographicfanduelplayer
boxscorefourfactorsv2
hustlestatsboxscore
boxscorematchups
boxscoremiscv2
playbyplayv2
boxscoreplayertrackv2
commonplayoffseries
boxscorescoringv2
commonplayoffseries
boxscoretraditionalv2
boxscoreusagev2
winprobabilitypbp
cumestatsplayergames
cumestatsplayer
cumestatsteamgames
cumestatsteam
draftcombinedrillresults
draftcombineplayeranthro
draftcombinenonstationaryshooting
draftcombinespotshooting
drafthistory
draftboard
playercompare
fantasywidget
franchisehistory
gamerotation
homepagev2
defensehub
leagueLeaders
leaguelineupviz
leaguedashlineups
leagueseasonmatchups
leaguedashplayerbiostats
leaguedashplayerclutch
playerestimatedmetrics
leaguedashplayerstats
leaguehustlestatsplayerleaders
leaguehustlestatsplayer
leagueplayerondetails
leaguedashplayershotlocations
leaguedashptdefend
leaguedashplayerptshot
leaguedashteamclutch
teamestimatedmetrics
leaguedashteamstats
leaguehustlestatsteamleaders
leaguehustlestatsteam
leaguedashteamshotlocations
leaguedashoppptshot
leaguedashteamptshot
matchupsrollup
playervsplayer
playerawards
playercareerbycollegerollup
playercareerbycollege
playercareerstats
playerfantasyprofilebargraph
playerfantasyprofile
playergamelog
playerprofilev2
commonallplayers
playerdashboardbyshootingsplits
playerdashboardbygeneralsplits
playerdashboardbyopponent
playerdashboardbylastngames
playerdashboardbygamesplits
playerdashboardbyclutch
playerdashboardbyteamperformance
playerdashboardbyyearoveryear
playerdashboardbygeneralsplits
commonplayerinfo
playerdashptshotdefend
playerdashptpass
playerdashptreb
playerdashptshots
playerdashptreboundlogs
playerdashptshotlog
playernextngames
dleaguepredictor
shotchartleaguewide
glalumboxscoresimilarityscore
boxscoresimilarityscore
playertrackbucketsimilarityscore
playertrackranksimilaritycomp
playertracksimilarityscore
playertracksimilarityuniqueness
synergybucketsimilarityscore
synergysimilarityscore
leaguestandingsv3
synergyplaytypes
franchiseplayers
teamgamelog
teamdashlineups
teamplayeronoffdetails
teamplayeronoffsummary
teamplayerdashboard
teamdetails
franchiseleaders
commonteamroster
teamyearbyyearstats
teamdashboardbyshootingsplits
teamdashboardbygeneralsplits
teamdashboardbyopponent
teamdashboardbylastngames
teamdashboardbygamesplits
teamdashboardbyclutch
teamdashboardbyteamperformance
teamdashboardbyyearoveryear
teamdashboardbygeneralsplits
teaminfocommon
teamdashptpass
teamdashptreb
teamdashptshots
videoStatus
teamandplayersvsplayers

swar avatar Aug 16 '20 00:08 swar

Here are some endpoints that I was not able to find with this method (I don't know if they are deprecated or not.)

allplayers
allstarballotpredictor
assisttracker
assisttrackerstats
boxscoreadvanced
boxscorefourfactors
boxscoremisc
boxscoreplayertracking
boxscorescoring
boxscoresummary
boxscoresummaryv2
boxscoretraditional
boxscoreusage
commonteamyears
draftcombineplayermeasurements
draftcombinestats
gleaguepredictor
homepage
homepageleaders
leaderstiles
leaguedashptstats
leaguedashptteamdefend
leaguegamefinder
leaguegamelog
leaguestandings
lineupstats
playbyplay
playbyplaymini
playerbiostats
playerclutchstats
playercomparestats
playerdefensestats
playergamelogs
playergamelogsstats
playergamesplitsstats
playergamestreakfinder
playergeneralsplitsstats
playerinfo
playerlastngamesstats
playerondetails
playeropponentstats
playerpassesstats
playerprofile
playerreboundsstats
playerscareerstats
playersclutchstats
playersdefensestats
playersgeneralstats
playershotchartdetail
playershotsstats
playershustleleaders
playershustlestats
playersshotlocationstats
playersshotstats
playerstrackingstats
playersvsplayers
playerteamperformancestats
playeryearoveryearstats
playoffpicture
playoffseries
scoreboard
scoreboardmini
scoreboardv2
shotchartdetail
shotchartlineupdetail
teamandplayervsplayers
teamclutchstats
teamfranchiseleaders
teamfranchiseleadersrank
teamgamelogs
teamgamesplitsstats
teamgamestreakfinder
teamgeneralsplitsstats
teamhistoricalleaders
teaminfo
teamlastngamesstats
teamlineupstats
teamopponentstats
teampassesstats
teamperformancestats
teamplayerstats
teamreboundsstats
teamroster
teamsclutchstats
teamsdefensestats
teamsgeneralstats
teamshootingsplitsstats
teamshotchartlineupdetail
teamshotsstats
teamshustleleaders
teamshustlestats
teamsshotlocationstats
teamsshotstats
teamsyearbyyearstats
teamvsplayer
teamyearoveryearstats
teamyears
videodetails
videoevents
winprobabilityplaybyplay

swar avatar Aug 16 '20 00:08 swar

Here are some that I didn't have that I will add to my analyzer:

alltimeleadersgrids
2assisttracker
cumestatsplayergames
cumestatsplayer
cumestatsteamgames
cumestatsteam
draftboard
gamerotation
leaguelineupviz
playerestimatedmetrics
leaguehustlestatsplayerleaders
leaguehustlestatsplayer
teamestimatedmetrics
leaguehustlestatsteamleaders
leaguehustlestatsteam
matchupsrollup
playercareerbycollegerollup
playercareerbycollege
dleaguepredictor
shotchartleaguewide
glalumboxscoresimilarityscore
boxscoresimilarityscore
playertrackbucketsimilarityscore
playertrackranksimilaritycomp
playertracksimilarityscore
playertracksimilarityuniqueness
synergybucketsimilarityscore
synergysimilarityscore
leaguestandingsv3

swar avatar Aug 16 '20 00:08 swar

Just re-ran this on https://www.nba.com/stats/ in the Console of the Chrome Dev Tools:

angular.module('nba-ng-hana-services')['_invokeQueue'].map(arr => arr[2][0])

EDIT: The original post parsed only the Angular service name....updated and re-ran the following in the Console of the Chrome Dev Tools:

angular.module('nba-ng-hana-services')['_invokeQueue'].map(s => typeof s[2][1][1] === 'function' ? s[2][1][1]().endpoint : null)

...and got this list (roughly, needed to do a bit of manual editing):

now = {
    "alltimeleadersgrids",
    "assistleaders",
    "assisttracker",
    "boxscoreadvancedv2",
    "boxscoredefensive",
    "boxscorefourfactorsv2",
    "boxscorematchups",
    "boxscoremiscv2",
    "boxscoreplayertrackv2",
    "boxscorescoringv2",
    "boxscoresimilarityscore",
    "boxscoretraditionalv2",
    "boxscoreusagev2",
    "commonallplayers",
    "commonplayerinfo",
    "commonplayoffseries",
    "commonteamroster",
    "cumestatsplayer",
    "cumestatsplayergames",
    "cumestatsteam",
    "cumestatsteamgames",
    "defensehub",
    "dleaguepredictor",
    "draftboard",
    "draftcombinedrillresults",
    "draftcombinenonstationaryshooting",
    "draftcombineplayeranthro",
    "draftcombinespotshooting",
    "drafthistory",
    "fantasywidget",
    "franchisehistory",
    "franchiseleaders",
    "franchiseplayers",
    "gamerotation",
    "glalumboxscoresimilarityscore",
    "homepagev2",
    "hustlestatsboxscore",
    "infographicfanduelplayer",
    "leaguedashlineups",
    "leaguedashoppptshot",
    "leaguedashplayerbiostats",
    "leaguedashplayerclutch",
    "leaguedashplayerptshot",
    "leaguedashplayershotlocations",
    "leaguedashplayerstats",
    "leaguedashptdefend",
    "leaguedashteamclutch",
    "leaguedashteamptshot",
    "leaguedashteamshotlocations",
    "leaguedashteamstats",
    "leaguehustlestatsplayer",
    "leaguehustlestatsplayerleaders",
    "leaguehustlestatsteam",
    "leaguehustlestatsteamleaders",
    "leagueLeaders",
    "leaguelineupviz",
    "leagueplayerondetails",
    "leagueseasonmatchups",
    "leaguestandingsv3",
    "matchupsrollup",
    "playbyplayv2",
    "playerawards",
    "playercareerbycollege",
    "playercareerbycollegerollup",
    "playercareerstats",
    "playercompare",
    "playerdashboardbygeneralsplits",
    "playerdashboardbyshootingsplits",
    "playerdashptpass",
    "playerdashptreb",
    "playerdashptreboundlogs",
    "playerdashptshotdefend",
    "playerdashptshotlog",
    "playerdashptshots",
    "playerestimatedmetrics",
    "playerfantasyprofile",
    "playerfantasyprofilebargraph",
    "playergamelog",
    "playernextngames",
    "playerprofilev2",
    "playertrackbucketsimilarityscore",
    "playertrackranksimilaritycomp",
    "playertracksimilarityscore",
    "playertracksimilarityuniqueness",
    "playervsplayer",
    "shotchartleaguewide",
    "synergybucketsimilarityscore",
    "synergyplaytypes",
    "synergysimilarityscore",
    "teamandplayersvsplayers"
    "teamdashboardbygeneralsplits",
    "teamdashboardbyshootingsplits",
    "teamdashlineups",
    "teamdashptpass",
    "teamdashptreb",
    "teamdashptshots",
    "teamdetails",
    "teamestimatedmetrics",
    "teamgamelog",
    "teaminfocommon",
    "teamplayerdashboard",
    "teamplayeronoffdetails",
    "teamplayeronoffsummary",
    "teamyearbyyearstats",
    "videodetails",
    "videoStatus",
    "winprobabilitypbp"

}

....and compared it with the list from August 2020 (copied from thread above):

then = {
    "alltimeleadersgrids",
    "assistleaders",
    "2assisttracker",
    "boxscoreadvancedv2",
    "boxscoredefensive",
    "infographicfanduelplayer",
    "boxscorefourfactorsv2",
    "hustlestatsboxscore",
    "boxscorematchups",
    "boxscoremiscv2",
    "playbyplayv2",
    "boxscoreplayertrackv2",
    "commonplayoffseries",
    "boxscorescoringv2",
    "commonplayoffseries",
    "boxscoretraditionalv2",
    "boxscoreusagev2",
    "winprobabilitypbp",
    "cumestatsplayergames",
    "cumestatsplayer",
    "cumestatsteamgames",
    "cumestatsteam",
    "draftcombinedrillresults",
    "draftcombineplayeranthro",
    "draftcombinenonstationaryshooting",
    "draftcombinespotshooting",
    "drafthistory",
    "draftboard",
    "playercompare",
    "fantasywidget",
    "franchisehistory",
    "gamerotation",
    "homepagev2",
    "defensehub",
    "leagueLeaders",
    "leaguelineupviz",
    "leaguedashlineups",
    "leagueseasonmatchups",
    "leaguedashplayerbiostats",
    "leaguedashplayerclutch",
    "playerestimatedmetrics",
    "leaguedashplayerstats",
    "leaguehustlestatsplayerleaders",
    "leaguehustlestatsplayer",
    "leagueplayerondetails",
    "leaguedashplayershotlocations",
    "leaguedashptdefend",
    "leaguedashplayerptshot",
    "leaguedashteamclutch",
    "teamestimatedmetrics",
    "leaguedashteamstats",
    "leaguehustlestatsteamleaders",
    "leaguehustlestatsteam",
    "leaguedashteamshotlocations",
    "leaguedashoppptshot",
    "leaguedashteamptshot",
    "matchupsrollup",
    "playervsplayer",
    "playerawards",
    "playercareerbycollegerollup",
    "playercareerbycollege",
    "playercareerstats",
    "playerfantasyprofilebargraph",
    "playerfantasyprofile",
    "playergamelog",
    "playerprofilev2",
    "commonallplayers",
    "playerdashboardbyshootingsplits",
    "playerdashboardbygeneralsplits",
    "playerdashboardbyopponent",
    "playerdashboardbylastngames",
    "playerdashboardbygamesplits",
    "playerdashboardbyclutch",
    "playerdashboardbyteamperformance",
    "playerdashboardbyyearoveryear",
    "playerdashboardbygeneralsplits",
    "commonplayerinfo",
    "playerdashptshotdefend",
    "playerdashptpass",
    "playerdashptreb",
    "playerdashptshots",
    "playerdashptreboundlogs",
    "playerdashptshotlog",
    "playernextngames",
    "dleaguepredictor",
    "shotchartleaguewide",
    "glalumboxscoresimilarityscore",
    "boxscoresimilarityscore",
    "playertrackbucketsimilarityscore",
    "playertrackranksimilaritycomp",
    "playertracksimilarityscore",
    "playertracksimilarityuniqueness",
    "synergybucketsimilarityscore",
    "synergysimilarityscore",
    "leaguestandingsv3",
    "synergyplaytypes",
    "franchiseplayers",
    "teamgamelog",
    "teamdashlineups",
    "teamplayeronoffdetails",
    "teamplayeronoffsummary",
    "teamplayerdashboard",
    "teamdetails",
    "franchiseleaders",
    "commonteamroster",
    "teamyearbyyearstats",
    "teamdashboardbyshootingsplits",
    "teamdashboardbygeneralsplits",
    "teamdashboardbyopponent",
    "teamdashboardbylastngames",
    "teamdashboardbygamesplits",
    "teamdashboardbyclutch",
    "teamdashboardbyteamperformance",
    "teamdashboardbyyearoveryear",
    "teamdashboardbygeneralsplits",
    "teaminfocommon",
    "teamdashptpass",
    "teamdashptreb",
    "teamdashptshots",
    "videoStatus",
    "teamandplayersvsplayers"
}

print(now - then)
print(then - now)

....and found some new endpoints (and possibly old endpoints):

{'assisttracker', 'videodetails', 'teamandplayersvsplayersteamdashboardbygeneralsplits'}

{'playerdashboardbyopponent', 'playerdashboardbyclutch', 'teamdashboardbygeneralsplits', 'playerdashboardbygamesplits', 'teamdashboardbyteamperformance', 'playerdashboardbylastngames', 'teamdashboardbyyearoveryear', 'teamdashboardbyclutch', 'teamdashboardbyopponent', 'teamdashboardbylastngames', 'teamandplayersvsplayers', 'playerdashboardbyteamperformance', 'playerdashboardbyyearoveryear', 'teamdashboardbygamesplits', '2assisttracker'}

@swar / @rsforbes - Is the endpoint generator (https://github.com/swar/nba_api/tree/master/tools/stats/endpoint_py_file_generator) the best way to add these endpoints?

timborden avatar Oct 11 '21 17:10 timborden