Unlocking the Power of Azure DevOps API: Fetching Modified Files in a PR using Python
Image by Nikos - hkhazo.biz.id

Unlocking the Power of Azure DevOps API: Fetching Modified Files in a PR using Python

Posted on

Are you tired of manually digging through pull requests to identify modified files? Do you wish there was a more efficient way to automate this process? Look no further! In this article, we’ll explore how to leverage the Azure DevOps API using Python to fetch all modified files in a pull request (PR). Buckle up, and let’s dive into the world of DevOps automation!

Getting Started: Setting up Azure DevOps API Access

Before we begin, you’ll need to set up API access to Azure DevOps. Follow these steps to get started:

  • Log in to your Azure DevOps organization and navigate to Personal Access Tokens (PATs).
  • Click on “New Token” and select “Read” access for “Code” under “Scopes”. You can also choose “Full” access if you want to perform more operations.
  • Name your token (e.g., “Python API Access”) and copy the token value. You’ll need this later.

Installing Required Python Packages

To interact with the Azure DevOps API, you’ll need to install the following Python packages:

pip install requests jsonpath-ng

Understanding Azure DevOps API Endpoints

The Azure DevOps API provides a vast range of endpoints to interact with various aspects of the platform. For our purpose, we’ll focus on the following endpoints:

  • GET https://dev.azure.com/{organization}/{project}/_apis/git/pullRequests/{pullRequestId}/commits?api-version=6.0: Retrieves a list of commits associated with a pull request.
  • GET https://dev.azure.com/{organization}/{project}/_apis/git/commits/{commitId}/changes?api-version=6.0: Retrieves a list of changes associated with a commit.

Writing Python Code to Fetch Modified Files

Now that we have our API access and required packages, let’s write a Python script to fetch all modified files in a PR:

import requests
import json

# Replace with your Azure DevOps organization and project names
organization = "your-organization"
project = "your-project"

# Replace with your PAT
pat = "your-pat-token"

# Set the pull request ID
pull_request_id = 12345

# Set API endpoint and headers
api_endpoint = f"https://dev.azure.com/{organization}/{project}/_apis/git/pullRequests/{pull_request_id}/commits?api-version=6.0"
headers = {
    "Authorization": f"Basic {pat}",
    "Content-Type": "application/json"
}

# Send GET request to retrieve commits
response = requests.get(api_endpoint, headers=headers)

# Parse JSON response
commits = response.json()["value"]

# Initialize an empty list to store modified files
modified_files = []

# Iterate through each commit
for commit in commits:
    # Extract commit ID
    commit_id = commit["commitId"]

    # Set API endpoint for commit changes
    changes_api_endpoint = f"https://dev.azure.com/{organization}/{project}/_apis/git/commits/{commit_id}/changes?api-version=6.0"

    # Send GET request to retrieve changes
    changes_response = requests.get(changes_api_endpoint, headers=headers)

    # Parse JSON response
    changes = changes_response.json()["value"]

    # Iterate through each change
    for change in changes:
        # Check if the change is a file modification
        if change["changeType"] == "edit":
            # Extract file path
            file_path = change["item"]["path"]

            # Add file path to modified files list
            modified_files.append(file_path)

# Print modified files
print("Modified files in PR:")
for file in modified_files:
    print(file)

Explanation of the Code

Let’s break down the code to understand what’s happening:

  1. We first set up the API endpoint and headers using our PAT and organization/project names.
  2. We send a GET request to retrieve a list of commits associated with the specified pull request ID.
  3. We iterate through each commit and extract the commit ID.
  4. For each commit, we send a GET request to retrieve a list of changes associated with the commit.
  5. We iterate through each change and check if it’s a file modification (edit).
  6. If it’s a file modification, we extract the file path and add it to our `modified_files` list.
  7. Finally, we print the list of modified files.

Handling Errors and Edge Cases

When working with APIs, it’s essential to handle errors and edge cases to ensure your script is robust. Here are some tips:

  • Handle API rate limiting by implementing exponential backoff or using the `requests-ratelimit` library.
  • Catch and handle exceptions for errors like invalid PAT, pull request not found, or API errors.
  • Implement retry logic to handle temporary errors or network issues.
  • Consider using pagination if you’re dealing with large pull requests or commits.

Conclusion

With this Python script, you’ve unlocked the power of the Azure DevOps API to fetch all modified files in a pull request. This automation can save you a significant amount of time and effort, allowing you to focus on more critical tasks. Remember to handle errors and edge cases to ensure your script is reliable and efficient.

If you’re interested in exploring more Azure DevOps API endpoints, be sure to check out the official Azure DevOps REST API documentation.

API Endpoint Description
GET https://dev.azure.com/{organization}/{project}/_apis/git/pullRequests/{pullRequestId}/commits?api-version=6.0 Retrieves a list of commits associated with a pull request.
GET https://dev.azure.com/{organization}/{project}/_apis/git/commits/{commitId}/changes?api-version=6.0 Retrieves a list of changes associated with a commit.

Happy coding, and don’t hesitate to ask if you have any questions or need further assistance!

Frequently Asked Question

Get ready to dive into the world of Azure DevOps API and Python, where we’ll explore the most frequently asked questions about fetching all modified files in a PR!

What Azure DevOps API endpoint should I use to fetch all modified files in a PR?

You should use the “Get Pull Request” endpoint, specifically the “Get Pull Request Changes” method, which returns a list of changes (including modified files) in a pull request. The API endpoint is: `GET https://dev.azure.com/{organization}/{project}/_apis/git/repositories/{repositoryId}/pullRequests/{pullRequestId}/changes?api-version=6.0`. Make sure to replace the placeholders with your actual values!

How do I authenticate with the Azure DevOps API using Python?

You can use the `requests` library in Python to authenticate with the Azure DevOps API using Personal Access Tokens (PATs) or OAuth. For PATs, simply include the token in the `Authorization` header of your request. For OAuth, you’ll need to obtain an access token and then use it in the `Authorization` header. You can also use the `azure-identity` library to handle authentication for you. Check out the Azure DevOps API documentation for more details on authentication methods!

What Python libraries do I need to fetch all modified files in a PR?

You’ll need the `requests` library to send HTTP requests to the Azure DevOps API. Additionally, you can use the `json` library to parse the JSON response from the API. If you want to handle authentication using OAuth, you’ll need the `azure-identity` library. Finally, you can use the `pprint` library to pretty-print the modified files list for easier debugging. Install them using pip: `pip install requests json azure-identity pprint`!

How do I parse the response from the Azure DevOps API to extract modified files?

Once you receive the response from the API, you can parse the JSON response using the `json` library. The response will contain a `changes` key, which is a list of changes. Iterate through the list and extract the `item` property, which contains the modified file information. You can access the file path, change type, and other properties using dot notation. For example: `response.json()[‘changes’][0][‘item’][‘path’]` would give you the file path of the first modified file!

Can I filter the modified files list to only include specific file types or paths?

Yes, you can filter the modified files list using Python’s list comprehension or conditional statements. For example, you can use a list comprehension to filter files by extension: `modified_files = [file for file in modified_files if file.path.endswith(‘.py’)]`. Alternatively, you can use an `if` statement to filter files by path or other criteria. Get creative with your filtering logic to extract the exact information you need!

Leave a Reply

Your email address will not be published. Required fields are marked *