campana
campana

Reputation: 167

python requests library to github api - inconsistent responses to same url

Appreciate any help - using Django and Github API for the first time together. I have a simple url that I get from an api request from a repo's pull requests. I'm looping through them getting to the diff_url property that I want to examine.

In the chrome browser, it works fine and I'm displaying the text output of the code differences for the pull. Looking at the network traffic, the network call is giving a 302 to another url which includes a token.

In incognito chrome as well as curl, I'm getting an 404 error.

I am using github3.py to get the pull model, and requests (with simple authentication) to try and access the diff_url from the pull model property.

I'm wondering why the browser works and neither the code nor curl will work at all.

Here is the Python code:

def getAllPullRequestsForRepo(self, repo_name):
    ''' Return pull request and tag object for repository 
    Github: Every pull request is an issue, but not every issue is a pull request
    For each pull request = issue - get associated labels
    '''
    # TODO look at repo array to get repository (save as object)
    repoOwner = self.org_name + '/' + repo_name
    github = Github(self.username, self.password)
    repository = github.get_repo(repoOwner)
    pullDict = []
    pulls = repository.get_pulls('all')
    pullDatum = {}

    for pull in pulls:
        assigneeName = ''
        assigneeLogin = ''
        if pull.assignee:
            assigneeName = pull.assignee.name
            assigneeLogin = pull.assignee.login

        pullDatum = {
            'id': pull.id,
            'assignee': assigneeName,
            'assignee_login': assigneeLogin,
            'title': pull.title,
            'body': pull.body,
            'state': pull.state,
            'created': pull.created_at,
            'diff_url': pull.diff_url,
            'diff_content': '',
            'issues_url': pull.issue_url,
            'issues_content': '',
            'commits_url': pull.commits_url,
            'commits_content': '',               
        }

        # Get the code differences and load into diff data
        diff_url_data = requests.get(pull.diff_url, auth=(self.username, self.password))

Upvotes: 2

Views: 967

Answers (1)

campana
campana

Reputation: 167

I reached out to the github api and happily they have great support and got back quickly with a nicely explained solution to this issue. Thank you Ivan! Here is their response, I hope it helps someone else out.

Thanks for reaching out. So, the reason why that's failing is that the diff_url points to a resource on github.com (the website), not a resource on api.github.com (the API). See the docs here:

https://developer.github.com/v3/pulls/#get-a-single-pull-request

"diff_url": "https://github.com/octocat/Hello-World/pull/1347.diff",

Because the resource is not served by the API, you can't use authentication mechanisms which are supported for the API (https://developer.github.com/v3/#authentication).

The website and the API don't share authentication mechanisms like that -- the website uses sessions, and the API uses stateless authentication via basic auth and tokens and such.

So, here's what you can do. You want to fetch the diff for the pull request, right? You can fetch that via the API as well, as documented here:

https://developer.github.com/v3/pulls/#custom-media-types

In other words, if you include a special media type in the accept header when fetching the pull request via the API -- you will get back the raw diff for that pull request.

Here's a curl example:

curl https://api.github.com/repos/rails/rails/pulls/30744 -H "Accept: application/vnd.github.v3.diff"

Hope this helps.

Best, Ivan

Upvotes: 1

Related Questions