How Do I Upload Crashes with Python?
If you'd like to bulk upload minidump files, you can download the following script as upload.py
and invoke it as follows, being sure to replace database
, application
, version
, and file.dmp
with values specific to your BugSplat configuration:
python upload.py database application version ./file.dmp
https://github.com/BugSplat-Git/python-crash-upload/blob/main/upload.py
import hashlib
import os
import requests
import sys
import zipfile
# Usage: python upload.py database application version ./file.dmp
def main():
if len(sys.argv) != 5:
print_usage()
exit(1)
database = sys.argv[1]
application = sys.argv[2]
version = sys.argv[3]
file = sys.argv[4]
if not os.path.exists(file):
print(f"Error: The file {file} does not exist.")
exit(1)
if not file.endswith(".dmp"):
print(f"Error: The file {file} is not a minidump.")
exit(1)
upload_minidump(database, application, version, file)
def upload_minidump(database, application, version, file):
try:
zip_file = create_zip(file)
file_size = os.path.getsize(zip_file)
upload_url = get_crash_upload_url(
database,
application,
version,
file_size
)
crash_type = 'Windows.Native'
crash_type_id = 1
upload_file_md5 = get_md5_hash(zip_file)
upload_file_to_presigned_url(upload_url, zip_file)
commit_s3_crash_upload(
upload_url,
database,
application,
version,
crash_type,
crash_type_id,
upload_file_md5
)
print("Uploaded minidump successfully")
except Exception as e:
print(e)
finally:
if os.path.exists(zip_file):
os.remove(zip_file)
def commit_s3_crash_upload(s3_key, database, application, version, crash_type, crash_type_id, md5):
route = f'https://{database}.bugsplat.com/api/commitS3CrashUpload'
files = {
'database': (None, database),
'appName': (None, application),
'appVersion': (None, version),
'crashType': (None, crash_type),
'crashTypeId': (None, str(crash_type_id)),
's3key': (None, s3_key),
'md5': (None, md5),
}
response = requests.post(route, files=files)
if response.status_code != 200:
raise Exception(f"Failed to commit S3 crash upload: {response.text}")
return response.json()
def create_zip(file):
zip_filename = file + ".zip"
with zipfile.ZipFile(zip_filename, 'w', zipfile.ZIP_DEFLATED) as zipf:
zipf.write(file, os.path.basename(file))
return zip_filename
def get_crash_upload_url(database, application, version, size):
route = f'https://{database}.bugsplat.com/api/getCrashUploadUrl?database={database}&appName={application}&appVersion={version}&crashPostSize={size}'
response = requests.get(route)
if response.status_code == 429:
raise Exception('Failed to get crash upload URL, too many requests')
if response.status_code != 200:
raise Exception('Failed to get crash upload URL')
json_response = response.json()
return json_response['url']
def get_md5_hash(file_path):
hash_md5 = hashlib.md5()
with open(file_path, "rb") as f:
for chunk in iter(lambda: f.read(4096), b""):
hash_md5.update(chunk)
return hash_md5.hexdigest()
def print_usage():
print("Usage: python upload.py <database> <application> <version> <file>")
def upload_file_to_presigned_url(presigned_url, file_path, additional_headers={}):
file_size = os.path.getsize(file_path)
headers = {
'content-type': 'application/octet-stream',
'content-length': str(file_size),
**additional_headers
}
with open(file_path, 'rb') as file:
response = requests.put(presigned_url, headers=headers, data=file)
if response.status_code != 200:
raise Exception(
f"Error uploading to presigned URL {presigned_url}")
return response
main()
Last updated
Was this helpful?