Skip to main content

Bitbucket Unofficial SDK

CI PyPI Python 3.14+ License: MIT Topics

Unofficial. This project is not affiliated with, endorsed by, or supported by Atlassian. "Bitbucket" is a trademark of Atlassian. Use at your own risk against the Bitbucket Cloud REST API.

Typed Python SDK for the Bitbucket Cloud REST API: repository core (CRUD, forks, hooks, permissions), refs (branches/tags), source, commits, downloads, and the full pull-request surface (comments, statuses, tasks, merging, default reviewers). Ships in two flavours — a sync client (BitbucketClient) backed by httpx.Client and an async client (AsyncBitbucketClient) backed by httpx.AsyncClient — with the same features and credential contract in both. Every response is a validated, frozen pydantic model with attribute access and real Python types — not a raw dict.

See docs/architecture/ for how the client is layered.

Table of contents

About

Bitbucket Cloud's REST API returns loosely shaped JSON and paginates by following next URLs. This SDK wraps it so a caller works with typed objects instead: one client per workspace or repository, lazy pagination, and a single credential contract shared by the sync and async clients.

Key features

  • Sync (BitbucketClient) and async (AsyncBitbucketClient) clients with the same endpoints.
  • Validated, frozen pydantic models for every response.
  • Lazy pagination through Page and paginate().
  • Retry and error mapping built into the transport.
  • Credentials read from arguments or environment and kept out of logs.

Installation

Install it from PyPI:

uv add bitbucket-unofficial-sdk

or with pip install bitbucket-unofficial-sdk. To try an unreleased commit, install it from git instead:

uv add "bitbucket-unofficial-sdk @ git+https://github.com/gajaguar/bitbucket-sdk"

Requirements

  • Python 3.14 or later. The floor is deliberate and can change.
  • Either an Atlassian email and API token, or a Bitbucket access token — see Authentication

Usage

List a repository's open pull requests:

from bitbucket import BitbucketClient

with BitbucketClient() as client:
    repository = client.default_workspace().repository("my-repo")

    for pull_request in repository.pull_requests.list(state="OPEN"):
        print(pull_request.id, pull_request.title)

Every list() method returns a lazy iterator that follows Bitbucket's next cursor; iterate it directly, wrap it in list(...), or call list_page(cursor=...) to manage pagination yourself. More examples — commenting, merging and waiting for the result, creating a repository — are in docs/api/recipes.md. The layout of the repository is in docs/architecture/project-layout.md.

Authentication

from bitbucket import BitbucketClient

# reads ATLASSIAN_USER_EMAIL and ATLASSIAN_API_TOKEN from the environment
client = BitbucketClient()

# or pass the email and API token explicitly
client = BitbucketClient(email="...", api_token="...")

# api_token accepts a zero-argument callable, invoked lazily on every request
client = BitbucketClient(email="...", api_token=lambda: keychain.current_token())

# access_token sends Authorization: Bearer and does not require an email
client = BitbucketClient(access_token="...")

# access_token also accepts a rotating or externally-managed provider
client = BitbucketClient(access_token=lambda: token_store.current_token())

The SDK accepts either basic credentials (email plus API token) or a bearer access token. Within each credential kind, the first source that has a value wins:

  1. A provider callable.
  2. An explicit string argument.
  3. An environment variable.

Between the two kinds, an explicit argument or provider beats the other kind's environment variable. If both kinds are explicit, or both are available only through the environment, the SDK raises ConfigurationError because the request is ambiguous. The resolver only reads or warns for the kind that wins.

ATLASSIAN_API_KEY is the former name of ATLASSIAN_API_TOKEN. It still works, with a DeprecationWarning, when ATLASSIAN_API_TOKEN is not set and basic credentials win.

Getting a credential

For an API token, open your profile menu and choose Account settings. Open the Security tab and choose Create and manage API tokens. Choose Create API token with scopes, select Bitbucket and the scopes your code needs, then copy the token. Atlassian shows it only once. API tokens are bound to your account and expire on the date you choose. Atlassian removed app passwords on 2026-07-28, so they no longer work.

For a bearer token, create a repository, project, or workspace access token in its Access tokens settings, or obtain an OAuth access token through the application's OAuth flow. The SDK uses the resulting token but does not obtain or refresh it.

What the SDK does not do

The SDK only reads the sources listed above. It has no OS keyring or keychain integration, no password-manager support, no OAuth flow, and no interactive prompts — those are application-level concerns for whatever consumes this SDK. The application is responsible for obtaining, refreshing and storing bearer tokens.

Protecting the token

A Bitbucket token grants the access of its scopes to everything it can reach. Never commit one, and rotate it immediately if it is exposed. The SDK never logs headers or its configuration, and credential values are excluded from repr(ClientConfig).

The full contract is in docs/sdk/credential-contract.md, and the values that belong to Bitbucket are in docs/sdk/credentials.md.

Async client

AsyncBitbucketClient mirrors the sync client one-for-one — same email/api_token/access_token/options, same workspace(), default_workspace(), .user, same resource tree (.pull_requests, .refs, .source, .commits, ...), and the same merge_and_wait polling helper. Single-shot methods are async def; auto-paginating methods return AsyncIterator.

from bitbucket import AsyncBitbucketClient
from bitbucket import MergeParameters

async with AsyncBitbucketClient() as client:
    repository = client.default_workspace().repository("my-repo")

    async for pull_request in repository.pull_requests.list(state="OPEN"):
        print(pull_request.id, pull_request.title)

    diff = await repository.pull_requests.diff(pull_request.id)

    status = await repository.pull_requests.merge_and_wait(
        pull_request.id,
        MergeParameters(merge_strategy="squash"),
    )
    print(status.task_status)

BasicAuth, BearerAuth and the credential-resolution rules (provider, env vars, deprecated ATLASSIAN_API_KEY) are shared between the sync and async clients, so the credential tests in docs/sdk/credential-tests.md apply to both.

Configuration

Variable Where it's read Default Description
ATLASSIAN_USER_EMAIL BitbucketClient() none Email of the Atlassian account, used for basic auth.
ATLASSIAN_API_TOKEN BitbucketClient() none API token, used for basic auth.
ATLASSIAN_API_KEY BitbucketClient() none Deprecated name of ATLASSIAN_API_TOKEN; emits a warning.
BITBUCKET_ACCESS_TOKEN BitbucketClient() none Bearer access token; no email is required.
BITBUCKET_WORKSPACE BitbucketClient.default_workspace() none Workspace slug used by default_workspace().

The names are exported as EMAIL_ENV_VAR, API_TOKEN_ENV_VAR, ACCESS_TOKEN_ENV_VAR and WORKSPACE_ENV_VAR, so an application does not have to repeat the strings.

Origin

Extracted from a larger internal toolkit's Bitbucket provider module, which had grown the whole project's maintenance surface. That toolkit keeps the provider-neutral pull-request seam (models, protocol, registry) and review-workflow logic (comment filtering and threading, reviewer-queue aggregation); this SDK carries only the Bitbucket wire client.

Contributing

See CONTRIBUTING.md.

Open items

  • Branch restrictions, branching model, projects, workspaces, and pipelines are not yet modeled — see docs/api/endpoint-coverage.md for the full endpoint matrix and docs/api/roadmap.md for the phased plan to full API parity.
  • A handful of Commits operations from the original Phase 2 estimate (a "file-conflicts" endpoint and up to 2 others) couldn't be confidently mapped to a real spec path without re-checking the live spec — see the note in docs/api/endpoint-coverage.md's Commits section.

License

MIT — see LICENSE.

Metadata

Release files for bitbucket-unofficial-sdk 0.6.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for bitbucket-unofficial-sdk 0.6.0
File Size Uploaded
bitbucket_unofficial_sdk-0.6.0.tar.gz 156.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for bitbucket-unofficial-sdk 0.6.0
File Interpreter ABI Platform
bitbucket_unofficial_sdk-0.6.0-py3-none-any.whl Python 3 none any Details

Total release size: 229.4 kB

Release files / bitbucket_unofficial_sdk-0.6.0.tar.gz

Download URL bitbucket_unofficial_sdk-0.6.0.tar.gz
Size 156.0 kB
Tags Source
SHA-256 checksum
How to use checksums
ce53d3506e97d00b50f7728242eb7fdb05afa1514af1b8b1bb666e2499ad2ead
BLAKE2b-256 checksum
How to use checksums
18d3ee2b7c0681b4ce4221be6c1bf34763f4fffbf95035887d1c491f06b2c41b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 1, 2026.

Transparency log

Release files / bitbucket_unofficial_sdk-0.6.0-py3-none-any.whl

Download URL bitbucket_unofficial_sdk-0.6.0-py3-none-any.whl
Size 73.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
41a9adb7a1f4fc1189ebe15783536d9e2828eee3053b0d056b94d2c17d5904eb
BLAKE2b-256 checksum
How to use checksums
c870de839e588c6adf56fa74d659b0a5c3aea8078a7b1b68d52e7352bfe6b6d4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 1, 2026.

Transparency log

Release history Release notifications | RSS feed

0.9.0

2 release files

0.8.0

2 release files

0.7.0

2 release files

This release

0.6.0 This release

2 release files

0.4.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page