So far I got this
async def download_raw_file_from_bitbucket(url: str) -> Optional[Any]:
parsed = _parse_bitbucket_url(url)if not BITBUCKET_EMAIL or not BITBUCKET_API_TOKEN:raise Exception("Missing Bitbucket email or API token") api_url = (f"https://api.bitbucket.org/2.0/repositories/" f"{parsed['workspace']}/{parsed['repo_slug']}/src/" f"{parsed['commit']}/{parsed['path']}" )async with aiohttp.ClientSession() as session:async with session.get( api_url,auth=aiohttp.BasicAuth(BITBUCKET_EMAIL, BITBUCKET_API_TOKEN),allow_redirects=True, ) as response:if not response.ok:raise Exception(f"{response.status} {await response.text()}") text = await response.text()try:return json.loads(text)except json.JSONDecodeError:return text
But no matter what I try, the response is always "Token is invalid, expired, or not supported for this endpoint.". I know the token is valid, it's freshly generated and has access to everything.
The URL look like this:
https://bitbucket.org/<username>/<repo>/<folder>/<folder>/<folder>/<folder>/file.extension
Hey @tomas.lopez
Welcome to the community!
From my observation, I believe your path is incorrect, which is why you receive an error indicating the token is invalid. Please try using this curl example with the API token and your path to see if you can download the files.
Example:
curl --request GET \ --url 'https://api.bitbucket.org/2.0/repositories/<Workspace>/<Repo>/src/<Branch>/<folder>/file.txt' \ --header 'Authorization: Bearer <access_token>' \ --header 'Accept: application/json'
Workspace: Your workspace nameRepo: Your repository nameBranch: Your branch where the file locatedPath: Your file path
The path you use doesn't include branch which is why it's failing. I suggest try above example to verify before applying it on your script
RegardsSyahrul
Hey! Thanks for the help. After your comment, I changed my code to this:
def _parse_bitbucket_url(value: str) -> Dict[str, str]:
parsed_url = urlparse(value)if not parsed_url.scheme or "bitbucket.org" not in parsed_url.netloc:raise Exception("Only links to bitbucket.org are supported") url_path = Path(parsed_url.path) parts = url_path.partsif len(parts) < 6 or parts[3] != "src":raise Exception("Unsupported Bitbucket URL structure") workspace = parts[1] repo_slug = parts[2] commit = parts[4] file_path = "/".join(parts[5:])return {"workspace": workspace,"repo_slug": repo_slug,"branch": commit,"path": file_path }async def download_raw_file_from_bitbucket(config: RunConfigurator, url: str) -> Optional[Any]: BITBUCKET_API_TOKEN = KeyManager(getattr(config, 'api_keys', {})).get_key("BITBUCKET_API_TOKEN") parsed = _parse_bitbucket_url(url) api_url = (f"https://api.bitbucket.org/2.0/repositories/" f"{parsed['workspace']}/{parsed['repo_slug']}/src/" f"{parsed['branch']}/{parsed['path']}" ) headers = {"Authorization": f"Bearer {BITBUCKET_API_TOKEN}","Accept": "application/json" }async with aiohttp.ClientSession() as session:async with session.get(api_url, headers=headers, allow_redirects=True) as response:if not response.ok:raise Exception(f"{response.status} {await response.text()}") text = await response.text()try:return json.loads(text)except json.JSONDecodeError:return text
But I still got the same "Token is invalid, expired, or not supported for this endpoint." error.
I tried with this cURL request:
curl -H "Authorization: Bearer <my token goes here>" -H "Accept: application/json" "https://api.bitbucket.org/2.0/repositories/<user>/<repo>/<folder>/<folder>/<folder>/<folder>/<file.extension>"
Hi @tomas.lopez
Understood. Could you tell me which access token you used? I tested with a repository access token that has read-only permissions and managed to download the files using the curl command I shared, without any problems. Please try that approach and let me know how it goes.
Thanks!Syahrul
Hey there!I'm working on it with @tomas.lopezI'll just answer on his behalf.
IT support told us: "The token is for a generic Atlassian account we have, 'user@company.com'. It has normal member permissions, so it doesnt have Admin permissions. There's only one way to create an API token within Atlassian as far as I am aware. Everyone can create one from their own account, but it's best to use a generic account in case of leavers etc. "What other info can I get for you? Thanks for your answers so far!
It looks like you're new here. Sign in or register to get started.