Forums

Articles
Create
cancel
Showing results for 
Search instead for 
Did you mean: 

Bitbucket Cloud REST API: encoding and decoding multipart messages in Python?

Ray Depew
Contributor
January 5, 2022 edited

Following up on my previous question

1. The Bitbucket Cloud REST API allows me to get a snippet in application/json, multipart/related, or multipart/form-data content types. The multipart content types include file contents, while the application/json content type includes links to the files on BB cloud. I have not yet succeeded at parsing the multipart output, separating it into the JSON metadata and the included files. How can I do that, using Python?

2. Similarly, the REST API allows me to create a snippet in multipart/related or multipart/form-data content types. I have successfully created an unnamed snippet using Python, but I have not successfully created a named snippet, or a snippet with one or more files in it. How can I do that, using Python?

I have successfully created named snippets with multiple files using cURL. I could include system calls to cURL in my Python code, but that's rather a kludge.

I've read the "Get a snippet" and "Create a snippet" sections of the REST API documentation several times, and I'm still stuck.

1 answer

1 accepted

0 votes
Answer accepted
Ray Depew
Contributor
January 7, 2022 edited

Well, I did the kludge. It took less time than learning how to deal with multipart messages.

Handling MIME multipart messages is a skill that has been around for decades (literally). It's a generic skill, not specific to any OS, software package, or entity. But it's something that I never learned. 

So I worked around it.

1. Getting and decoding the snippet: Armed with a username and an app password, I used Python's requests library to retrieve the snippet from the local server. The entire contents of the snippet was wrapped up in one JSON object. (EDIT: my original editing was too vigorous. The local server doesn't need an app password But the next step does.)


def get_snippet_from_cloud(snippet_name, user, app_passwd):
url = 'https://api.bitbucket.org/2.0/snippets/{0}/{1}'.format(workspace, snippetName)
r = requests.get(url, auth=(user, passwd), headers={ "Accept": "application/json" })
return r.json()

Parsing the JSON object to retrieve the contents was a simple matter.

2. Encoding and writing the snippet: I used the os.system call to execute cURL from the command line. By using the -F option, I created a multipart POST request without having to assemble the multipart message first.

def write_snippet_to_cloud(source_path, workspace, user, app_passwd):
url = 'https://api.bitbucket.org/2.0/snippets/{0}'.format(workspace)
auth = "{0}:{1}".format(user, app_passwd)
header = "'Content-Type: application/json'"
title = get_title(source_path) # get_title() returns a string
files = get_files(source_path) # get_files() returns a list of filenames
curl_cmd = "curl -u {0} --request POST {1} -F title=\"{2}\"".format(auth, url, title)
for f in files:
curl_cmd = "{0} -F file=@{1}".format(curl_cmd, os.path.join(source_path, f))
response = os.system(curl_cmd)
if response == 0:
print("\n\nSnippet '{0}' successfully created".format(title))

 The code can be cleaned up considerably, but it does the job.

EDITED TO ADD: This was all done in Linux. It can be done in Windows as well -- but since curl is an alias for PowerShell's Invoke-WebRequest, the curl_cmd strings will need to be rewritten to conform to the Invoke-WebRequest syntax.

Suggest an answer

Log in or Sign up to answer
DEPLOYMENT TYPE
CLOUD
TAGS
AUG Leaders

Atlassian Community Events