I want to retrieve all pull request ids from a repository but I get stuck with log in.
Not sure what account I get. I dont know the distinction between service account and user account. I signed up with bitbucket ages ago .
import requests
import os
from typing import List, Optional, Dict, Any
def get_all_pr_ids(
workspace: str,
repo_slug: str,
username: str,
app_password: str,
state: Optional[str] = None # 'OPEN', 'MERGED', 'DECLINED', 'SUPERSEDED'
) -> Optional[List[int]]:
"""
Retrieves the IDs of all pull requests in a Bitbucket Cloud repository.
Args:
workspace (str): The Bitbucket workspace ID (e.g., 'your-company-workspace').
repo_slug (str): The repository slug (e.g., 'my-awesome-repo').
username (str): Your Bitbucket username (email or username).
app_password (str): Your Bitbucket app password with 'pullrequests:read' permission.
state (Optional[str]): Filter PRs by state. Can be 'OPEN', 'MERGED', 'DECLINED', 'SUPERSEDED'.
If None, retrieves all PRs regardless of state.
Returns:
Optional[List[int]]: A list of pull request IDs, or None if an error occurs.
"""
base_url = f"https://api.bitbucket.org/2.0/repositories/{workspace}/{repo_slug}/pull-requests"
# base_url = f"https://bitbucket.org/{workspace}/{repo_slug}/pull-requests"
params: Dict[str, Any] = {'pagelen': 100} # Fetch 100 PRs per page (max is 100)
if state:
params['state'] = state.upper() # Ensure state is uppercase for API
all_pr_ids: List[int] = []
next_page_url: Optional[str] = base_url
while next_page_url:
print(f"Fetching PRs from: {next_page_url}")
try:
response = requests.get(next_page_url, auth=(username, app_password),
params=params if next_page_url == base_url else None)
response.raise_for_status() # Raise an HTTPError for bad responses (4xx or 5xx)
data = response.json()
for pr in data.get('values', []):
all_pr_ids.append(pr['id'])
next_page_url = data.get('next') # Get URL for the next page, if any
# For subsequent pages, the 'next' URL already contains the necessary parameters,
# so we don't need to pass 'params' again. Reset params for the loop.
params = {}
except requests.exceptions.HTTPError as e:
print(f"HTTP error occurred: {e}")
print(f"Response content: {e.response.text}")
if e.response.status_code == 404:
print(f"Repository {workspace}/{repo_slug} not found or no pull requests.")
elif e.response.status_code == 401:
print("Authentication failed. Check your username and app password.")
return None
except requests.exceptions.ConnectionError as e:
print(f"Connection error occurred: {e}")
return None
except requests.exceptions.Timeout as e:
print(f"Timeout error occurred: {e}")
return None
except requests.exceptions.RequestException as e:
print(f"An unexpected error occurred: {e}")
return None
except Exception as e:
print(f"An unexpected error occurred during JSON parsing or data access: {e}")
return None
return all_pr_ids
if __name__ == "__main__":
# --- Configuration (Replace with your actual details) ---
# It's highly recommended to use environment variables for sensitive information
# rather than hardcoding them directly in the script.
BITBUCKET_USERNAME = os.getenv("BITBUCKET_USERNAME", "correctid")
BITBUCKET_APP_PASSWORD = os.getenv("BITBUCKET_APP_PASSWORD", "correctpw")
BITBUCKET_WORKSPACE = os.getenv("BITBUCKET_WORKSPACE", "correctworkspace") # e.g., 'my-company'
BITBUCKET_REPO_SLUG = os.getenv("BITBUCKET_REPO_SLUG", "correctrepo") # e.g., 'project-x'
# Optional: Filter by PR state. Uncomment and set to one of:
# 'OPEN', 'MERGED', 'DECLINED', 'SUPERSEDED'
PR_STATE_FILTER: Optional[str] = None # Set to 'OPEN' to get only open PRs, etc.
# --- Check if default values are still present ---
if "your_bitbucket_username" in BITBUCKET_USERNAME or \
"your_bitbucket_app_password" in BITBUCKET_APP_PASSWORD or \
"your-workspace-id" in BITBUCKET_WORKSPACE or \
"your-repository-slug" in BITBUCKET_REPO_SLUG:
print(
"WARNING: Please update the placeholder values for BITBUCKET_USERNAME, BITBUCKET_APP_PASSWORD, BITBUCKET_WORKSPACE, and BITBUCKET_REPO_SLUG.")
print("You can set them as environment variables or directly in the script for testing.")
# For a real scenario, you'd stop here.
# exit(1) # Uncomment this to force exit if not configured
print(f"Retrieving all pull request IDs for {BITBUCKET_WORKSPACE}/{BITBUCKET_REPO_SLUG}...")
if PR_STATE_FILTER:
print(f"Filtering by state: {PR_STATE_FILTER}")
pr_ids = get_all_pr_ids(
workspace=BITBUCKET_WORKSPACE,
repo_slug=BITBUCKET_REPO_SLUG,
username=BITBUCKET_USERNAME,
app_password=BITBUCKET_APP_PASSWORD,
state=PR_STATE_FILTER
)
if pr_ids is not None:
if pr_ids:
print(f"\nFound {len(pr_ids)} pull request(s):")
for pr_id in pr_ids:
print(f"- PR ID: {pr_id}")
else:
print("\nNo pull requests found for the specified criteria in this repository.")
else:
print("\nFailed to retrieve pull request IDs due to an error.")
The original base_url ends with pullrequests without a hyphen. No difference whether I add back a hypen or not