Sabbir Ahmed

Sabbir Ahmed

1 week ago

Bitbucket API with Real-World Examples and Code


What Is the Bitbucket API?


Imagine you have a magic box where you store all your books, and every time you need one, you simply press a button to get it delivered. Bitbucket is like that magic box but for developers—it stores their code! Now, to communicate with this magic box without actually opening it, you use something called an API (Application Programming Interface). Think of the API as a special remote control that helps you interact with Bitbucket's code repository from anywhere.


Story: Meet Alex the Developer


Alex is a curious programmer who loves building small apps with his friends. One day, Alex's elder brother Fahim introduces him to Bitbucket and its API.

"Why do we need this API thingy?" Alex asked. Fahim replied, "Imagine you could tell Bitbucket to do stuff for you, like pulling code from a repository or even creating new branches automatically, without logging in every time. That’s exactly what the Bitbucket API does—it helps us talk to Bitbucket programmatically!"

Excited, Alex decided to learn more. Let’s join Alex on his journey to discover the wonders of the Bitbucket API.


How Does Bitbucket API Work?


The Bitbucket API works like a post office. You send a "request" to Bitbucket's servers, asking it to do something, and Bitbucket replies with a "response." Here’s how it goes:


  • Request: You ask something using HTTP methods like GET (to fetch data), POST (to create something), PUT (to update), or DELETE.
  • Authentication: You must prove who you are using tokens or credentials.
  • Response: Bitbucket gives you the result in a language called JSON, which is easy to read for both humans and computers.

Let’s Play with the API (Hands-On Example)


Fahim gave Alex a small exercise: "Let’s fetch all the repositories in my Bitbucket account!"


Set Up Authentication


Bitbucket requires an OAuth token or personal credentials. Alex used Python to make the process easier.


import requests

# Replace 'your_username' and 'your_app_password'
auth = ('your_username', 'your_app_password')
url = "https://api.bitbucket.org/2.0/repositories/your_username"

response = requests.get(url, auth=auth)
if response.status_code == 200:
    print(response.json())
else:
    print("Something went wrong!", response.status_code)

Understand the JSON Response


Alex saw a list of repositories with details like their name, creation date, and owner. It looked like this:


{
    "values": [
        {
            "name": "my-first-repo",
            "owner": "Alex",
            "created_on": "2023-01-01"
        },
        ...
    ]
}

Build Something Cool


Alex wrote a script to display the repository names in a neat list:


data = response.json()
for repo in data['values']:
    print(f"Repository Name: {repo['name']}")

Why Should You Use Bitbucket API?


Alex found the API so useful that he listed some reasons why others should use it too:


  • Automate Tasks: Fetch updates, merge pull requests, or manage branches without logging into the dashboard.
  • Integrate Tools: Combine Bitbucket with other apps like Jenkins or Slack for better workflows.
  • Custom Dashboards: Build personalized tools to monitor repositories or commit histories.
  • Simplify Workflows: Save time by automating repetitive tasks.

Exploring More Features


Here’s what Alex learned as he dived deeper:


Create a New Repository


Want to create a repository on the fly? Use the following code:


payload = {
    "scm": "git",
    "is_private": True,
    "name": "new-repo"
}
response = requests.post(url, json=payload, auth=auth)
print(response.json())

Manage Pull Requests


Bitbucket API helps manage pull requests too:


  • Fetch open PRs.
  • Merge or decline PRs automatically.

Webhooks


Alex used webhooks to get notifications whenever someone pushed new code to a repository.


Advanced Use Cases of Bitbucket API


Once you understand the basics of the Bitbucket API, you can dive into more advanced use cases. Here are a few practical implementations that developers often utilize:


Fetching Commit History


Alex wanted to track the commit history of a specific repository to analyze changes over time. Using the API, he fetched the commit details with ease:


import requests

# Replace 'your_username', 'your_app_password', and 'repo_slug'
auth = ('your_username', 'your_app_password')
url = "https://api.bitbucket.org/2.0/repositories/your_username/repo_slug/commits"

response = requests.get(url, auth=auth)
if response.status_code == 200:
    commits = response.json()
    for commit in commits['values']:
        print(f"Commit: {commit['hash']} - {commit['message']}")
else:
    print("Failed to fetch commits", response.status_code)

Branch Management with API


To streamline his workflow, Alex automated the creation and deletion of branches in his repository. Here's how he created a new branch using the Bitbucket API:


import requests

# Replace 'your_username', 'your_app_password', 'repo_slug', and 'branch_name'
auth = ('your_username', 'your_app_password')
url = "https://api.bitbucket.org/2.0/repositories/your_username/repo_slug/refs/branches"
payload = {
    "name": "branch_name",
    "target": {
        "hash": "default"  # Use the hash of the branch/commit you want to base this on
    }
}

response = requests.post(url, json=payload, auth=auth)
if response.status_code == 201:
    print("Branch created successfully!")
else:
    print("Failed to create branch", response.status_code)

Integrating Bitbucket with Jenkins


Many developers use the Bitbucket API to integrate their repositories with Jenkins for Continuous Integration/Continuous Deployment (CI/CD). Alex learned how to set up a webhook that triggers Jenkins builds on every push:


import requests

# Replace 'your_username', 'your_app_password', and 'repo_slug'
auth = ('your_username', 'your_app_password')
url = f"https://api.bitbucket.org/2.0/repositories/your_username/repo_slug/hooks"
payload = {
    "description": "Jenkins Trigger",
    "url": "http://your-jenkins-url/bitbucket-hook/",
    "active": True,
    "events": ["repo:push"]
}

response = requests.post(url, json=payload, auth=auth)
if response.status_code == 201:
    print("Webhook created successfully!")
else:
    print("Failed to create webhook", response.status_code)

Analyzing Repository Metrics


To monitor project health, Alex built a dashboard to analyze metrics like the number of commits, branches, and pull requests. Here's how he fetched repository statistics:


import requests

# Replace 'your_username' and 'your_app_password'
auth = ('your_username', 'your_app_password')
url = "https://api.bitbucket.org/2.0/repositories/your_username/repo_slug"

response = requests.get(url, auth=auth)
if response.status_code == 200:
    repo_data = response.json()
    print(f"Repository: {repo_data['name']}")
    print(f"Main Branch: {repo_data['mainbranch']['name']}")
    print(f"Number of Forks: {repo_data['forks_count']}")
    print(f"Number of Watchers: {repo_data['watchers']['count']}")
else:
    print("Failed to fetch repository data", response.status_code)

Bitbucket API Rate Limiting


While experimenting, Alex discovered that the Bitbucket API has rate limits to prevent abuse. Here's how he implemented a retry mechanism for his API calls:


import requests
import time

auth = ('your_username', 'your_app_password')
url = "https://api.bitbucket.org/2.0/repositories/your_username/repo_slug"

def fetch_data_with_retry(url, retries=3):
    for attempt in range(retries):
        response = requests.get(url, auth=auth)
        if response.status_code == 200:
            return response.json()
        elif response.status_code == 429:  # Too many requests
            print("Rate limit exceeded, retrying...")
            time.sleep(2 ** attempt)  # Exponential backoff
        else:
            print(f"Failed with status: {response.status_code}")
            break
    return None

data = fetch_data_with_retry(url)
if data:
    print(f"Repository Name: {data['name']}")

Securing API Access


Alex also learned the importance of securing API access. He configured environment variables for sensitive credentials like usernames and passwords:


import os
import requests

# Set environment variables for username and password
auth = (os.getenv('BITBUCKET_USERNAME'), os.getenv('BITBUCKET_APP_PASSWORD'))
url = "https://api.bitbucket.org/2.0/repositories/your_username/repo_slug"

response = requests.get(url, auth=auth)
if response.status_code == 200:
    print("Secure connection established!")
else:
    print("Failed to connect securely", response.status_code)

Using Bitbucket API for Pull Request Automation


One of the most powerful features of the Bitbucket API is managing pull requests programmatically. Alex learned how to use the API to automate tasks like creating, reviewing, and merging pull requests. This significantly improved his team’s workflow.


Creating a Pull Request


To create a pull request between two branches, Alex used the following script:


import requests

# Replace 'your_username', 'your_app_password', 'repo_slug', 'source_branch', and 'destination_branch'
auth = ('your_username', 'your_app_password')
url = f"https://api.bitbucket.org/2.0/repositories/your_username/repo_slug/pullrequests"
payload = {
    "title": "New Feature Implementation",
    "source": {"branch": {"name": "source_branch"}},
    "destination": {"branch": {"name": "destination_branch"}},
    "description": "This pull request adds new features and fixes several bugs."
}

response = requests.post(url, json=payload, auth=auth)
if response.status_code == 201:
    print("Pull request created successfully!")
else:
    print("Failed to create pull request", response.status_code)

Fetching Pull Request Details


To view details of all open pull requests in a repository, Alex used the following script:


import requests

# Replace 'your_username', 'your_app_password', and 'repo_slug'
auth = ('your_username', 'your_app_password')
url = f"https://api.bitbucket.org/2.0/repositories/your_username/repo_slug/pullrequests"

response = requests.get(url, auth=auth)
if response.status_code == 200:
    pull_requests = response.json()
    for pr in pull_requests['values']:
        print(f"Title: {pr['title']}, Status: {pr['state']}, Created On: {pr['created_on']}")
else:
    print("Failed to fetch pull requests", response.status_code)

Merging a Pull Request


When a pull request is approved, Alex automated the merge process using the following script:


import requests

# Replace 'your_username', 'your_app_password', 'repo_slug', and 'pull_request_id'
auth = ('your_username', 'your_app_password')
url = f"https://api.bitbucket.org/2.0/repositories/your_username/repo_slug/pullrequests/pull_request_id/merge"

response = requests.post(url, auth=auth)
if response.status_code == 200:
    print("Pull request merged successfully!")
else:
    print("Failed to merge pull request", response.status_code)

Tracking Code Deployments Using Bitbucket API


Alex also explored how to track code deployments by tagging commits and monitoring deployment activities through the Bitbucket API.


Tagging Commits


To tag specific commits, Alex used the following script:


import requests

# Replace 'your_username', 'your_app_password', 'repo_slug', and 'commit_hash'
auth = ('your_username', 'your_app_password')
url = f"https://api.bitbucket.org/2.0/repositories/your_username/repo_slug/refs/tags"
payload = {
    "name": "v1.0.0",
    "target": {"hash": "commit_hash"}
}

response = requests.post(url, json=payload, auth=auth)
if response.status_code == 201:
    print("Tag created successfully!")
else:
    print("Failed to create tag", response.status_code)

Tracking Deployment Pipelines


By integrating deployment pipelines with Bitbucket API, Alex monitored the status of deployments and ensured everything was running smoothly. Here’s how:


import requests

# Replace 'your_username', 'your_app_password', and 'repo_slug'
auth = ('your_username', 'your_app_password')
url = f"https://api.bitbucket.org/2.0/repositories/your_username/repo_slug/deployments"

response = requests.get(url, auth=auth)
if response.status_code == 200:
    deployments = response.json()
    for deployment in deployments['values']:
        print(f"Environment: {deployment['environment']['name']}, Status: {deployment['state']}")
else:
    print("Failed to fetch deployments", response.status_code)

Using API for Rollbacks


In case of an issue, Alex automated rollbacks by deploying a previous tag:


import requests

# Replace 'your_username', 'your_app_password', 'repo_slug', and 'tag_name'
auth = ('your_username', 'your_app_password')
url = f"https://api.bitbucket.org/2.0/repositories/your_username/repo_slug/deployments"
payload = {
    "deployment_environment": "staging",
    "tag": "tag_name"
}

response = requests.post(url, json=payload, auth=auth)
if response.status_code == 201:
    print("Rollback deployed successfully!")
else:
    print("Failed to deploy rollback", response.status_code)

Conclusion


By the end of his journey, Alex could automate most tasks with the Bitbucket API, making his workflow faster and smarter. He shared this knowledge with his friends, inspiring them to explore APIs.

So, what’s stopping you? Start exploring the Bitbucket API today and unlock endless possibilities for automating and simplifying your development workflow.

Comments

Login As User
Word Count: 0