简体   繁体   中英

How to increase your limit of Github API uses per hour in Javascript

I'm trying to work pull requests, issues, and commits with repos and I have the following code:

const axios = require('axios');
var gitPullApiLink = "https://api.github.com/repos/elixir-lang/elixir/pulls";
var listOfCommits = [];
var listOfSHAs = [];
var mapOfInfoObjects = new Map();
var mapPullRequestNumberToCommits = new Map();
var mapPRNumbersToCommitObjects = new Map();
var listOfPrObjects = [];
var setOfFileObjects = new Set();
var listOfNumbersOfTargetedIssues = [];
var mapPRnumberToCloseOpenDateObjects = new Map();

class PullRequestParser {

async getListOfPullRequests(pullrequestLink) {
    const message = await axios.get(pullrequestLink);
    //console.log(message);
    listOfPrObjects = message['data'];
}

async getCommitsForEachPullRequestAndPRinformation() {
    var listOfPrNumbers = [];
    var k;
    // this loop will just make a list of Pull Request Numbers
    for (k = 0; k < listOfPrObjects.length; k++){
        var currPrNumber = listOfPrObjects[k]['number'];
        listOfPrNumbers.push(currPrNumber);
    }
    // I created a separate list just because... I did it this way because on the github API website it seems
    // like the pull request has the same number as the issue it affects. I explain how you can see this down below
    listOfNumbersOfTargetedIssues = listOfPrNumbers;
    // next loop will make objects that contain information about each pull request.
    var n;
    for (n = 0; n < listOfPrNumbers; n++){
        var ApiLinkForEachPullRequest = gitPullApiLink + "/" + listOfPrNumbers[n];
        const mes = await axios.get(ApiLinkForEachPullRequest);
        var temp = {OpeningDate: mes['data']['created_at'],
            ClosingDate: mes['data']['closed_at'],
            IssueLink: mes['data']['_links']['issue']['href']};
        //mapPRnumberToCloseOpenDateObjects will be a map where the key is the pull request number and the value
        // is the object that stores the open date, close date, and issue link for that pull request. The reason
        // why I said I think the pull request number is the same as the number of the issue it affects is because
        // if you take any object from the map, say you do mapPRnumberToCloseOpenDateObjects.get(10). You'll
        // get an object with a pull request number 10. Now if you take this object and look at it's "IssueLink"
        // field, the very last part of the link will have the number 10, and if you look at the github API
        // it says for a single issue, you do: /repos/:owner/:repo/issues/:issue_number <---- As you can see,
        // the IssueLink field will have this structure and in place of the issue_number, the field will be 10
        // for our example object.
        mapPRnumberToCloseOpenDateObjects.set(listOfPrNumbers[n], temp);
    }
    //up to this point, we have the pull request numbers. we will now start getting the commits associated with
    //each pull request
    var j;
    for (j = 0; j < listOfPrNumbers.length; j++){
        var currentApiLink = gitPullApiLink + "/" + listOfPrNumbers[j] + "/commits";
        const res = await axios.get(currentApiLink);
        //here we map a single pull request to the information containing the commits. I'll just warn you in
        // advance: there's another object called mapPRNumbersToCommitObjects. THIS MAP IS DIFFERENT! I know it's
        // subtle, but I hope the language can make the distinction: mapPullRequestNumberToCommits will just
        // map a pull request number to some data about the commits it's linked to. In contrast,
        // mapPRNumbersToCommitObjects will be the map that actually maps pull request numbers to objects
        // containing information about the commits a pull request is associated with!
        mapPullRequestNumberToCommits.set(listOfPrNumbers[j], res['data']);
    }
    // console.log("hewoihoiewa");
}

async createCommitObjects(){
    var x;
    // the initial loop using x will loop over all pull requests and get the associated commits
    for (x = 0; x < listOfPrObjects.length; x++){
        //here we will get the commits
        var currCommitObjects = mapPullRequestNumberToCommits.get(listOfPrObjects[x]['number']);
        //console.log('dhsiu');
        // the loop using y will iterate over all commits that we get from a single pull request
        var y;
        for (y = 0; y < currCommitObjects.length; y++){

            var currentSHA = currCommitObjects[y]['sha'];
            listOfSHAs.push(currentSHA);
            var currApiLink = "https://api.github.com/repos/elixir-lang/elixir/commits/" + currentSHA;
            const response = await axios.get(currApiLink,);
            //console.log("up to here");
            // here we start extracting some information from a single commit
            var currentAuthorName = response['data']['commit']['committer']['name'];
            var currentDate = response['data']['commit']['committer']['date'];
            var currentFiles = response['data']['files'];
            // this loop will iterate over all changed files for a single commit. Remember, every commit has a list
            // of changed files, so this loop will iterate over all those files, get the necessary information
            // from those files.
            var z;
            // we create this temporary list of file objects because for every file, we want to make an object
            // that will store the necessary information for that one file. after we store all the objects for
            // each file, we will add this list of file objects as a field for our bigger commit object (see down below)
            var tempListOfFileObjects = [];
            for (z = 0; z < currentFiles.length; z++){
                var fileInConsideration = currentFiles[z];
                var nameOfFile = fileInConsideration['filename'];
                var numberOfAdditions = fileInConsideration['additions'];
                var numberOfDeletions = fileInConsideration['deletions'];
                var totalNumberOfChangesToFile = fileInConsideration['changes'];
                //console.log("with file");
                var tempFileObject = {fileName: nameOfFile, totalAdditions: numberOfAdditions,
                    totalDeletions: numberOfDeletions, numberOfChanges: totalNumberOfChangesToFile};
                // we add the same file objects to both a temporary, local list and a global set. Don't be tripped
                // up by this; they're doing the same thing!
                setOfFileObjects.add(tempFileObject);
                tempListOfFileObjects.push(tempFileObject);
            }
            // here we make an object that stores information for a single commit. sha, authorName, date are single
            // values, but files will be a list of file objects and these file objects will store further information
            // for each file.
            var tempObj = {sha: currentSHA, authorName: currentAuthorName, date: currentDate, files: tempListOfFileObjects};
            var currPrNumber = listOfPrObjects[x]['number'];

            console.log(currPrNumber);
            // here we will make a single pull request number to an object that will contain all the information for
            // every single commit associated with that pull request. So for every pull request, it will map to a list
            // of objects where each object stores information about a commit associated with the pull request.
            mapPRNumbersToCommitObjects.set(currPrNumber, tempObj);
        }
    }
    return mapPRNumbersToCommitObjects;
}

async startParsingPullRequests() {
    this.getListOfPullRequests(gitPullApiLink  + "?state=all").then(() => {
        this.getCommitsForEachPullRequestAndPRinformation().then(() => {
            this.createCommitObjects().then((response) => {
                console.log("functions were successful");
                return new mapPRNumbersToCommitObjects;
                //return mapPRNumbersToCommitObjects;
            }).catch((error) => {
                console.log("printing first error");
                console.log(error);
            })
        }).catch((error2) => {
            console.log("printing the second error");
            console.log(error2);
        })
    }).catch((error3) => {
        console.log("printing the third error");
        console.log(error3);
    });
}

//adding some getter methods so they can be used to work with whatever information people may need.
//I start all of them with the this.startParsingPullRequests() method because by calling that method 
it gets all
// the information for the global variables.

async getSetOfFileObjects(){
    var dummyMap = await this.startParsingPullRequests();
    return {files: setOfFileObjects, prMap: mapPRnumberToCloseOpenDateObjects};
}

async OpenCloseDateObjects(){
    var dummyMap = await this.startParsingPullRequests();
    return mapPRnumberToCloseOpenDateObjects;
}

async getNumbersOfTargetedIssues(){
    var dummyMap = await this.startParsingPullRequests();
    return listOfNumbersOfTargetedIssues;
}

}

var dummy = new PullRequestParser();
var dummyMap = dummy.startParsingPullRequests().then((message) => {
console.log("dummyMap is defined! :)");
console.log(dummyMap);
});

module.exports = PullRequestParser;

Whenever I run the code on the webstorm terminal though, with:

node PullRequestParser.js

I get a 403 error, followed by a bunch of error output, with the following statement:

data: {
  message: "API rate limit exceeded for 138.186.17.173. (But here's the good news: Authenticated 
requests get a higher rate limit. Check out the documentation for more details.)"

I looked up the documentation for this and found out that without authentication, I can make 60 requests per hour to a repo. In order to get authentication, however, the only example provided is an example they provide by using the command line. I don't think this would be enough though because I want to do some further analysis with the results I get. Does anybody know how I can increase the number of requests I can make? Where in the code would I need to make changes and what kind of changes would I need to make? Thanks!

The first line of the documentation says everything you need to know.

For API requests using Basic Authentication or OAuth, you can make up to 5000 requests per hour.

Using Basic Authentication is pretty simple, so that may be the easiest thing to get you up and running. OAuth is more complicated, but more desirable in production.

The axios library supports basic auth requests out of the box.

async getListOfPullRequests(pullrequestLink) {
    const message = await axios.get(pullrequestLink, {
        auth: {
            username: 'username',
            password: 'password'
        }
    });
    //console.log(message);
    listOfPrObjects = message['data'];
}

You just need to supply the correct username and password information.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM