How to download files with Box API & Python - python

I have currently the upload portion of my code working, how would I go about converting this into a program that will download the respective files from the box folder?
This is the upload program:
import requests
import json
#the user acces token
access_token = 'UfUNeHhv4gIxFCn5WEXHgBJwfG8gHT2o'
#the name of the file as you want it to appear in box
dst_filename = 'box_file'
#the actual file path
src_directory = 'C:\Python\cache\\'
#the name of the file to be transferred
src_filename = 'Wildlife.wmv'
#the id of the folder you want to upload to
parent_id = '0'
counter = 1
for counter in range(1, 6):
src_file = (src_directory + src_filename + '-' + str(counter))
print(src_file)
box_filename = (dst_filename + '-' + str(counter))
headers = { 'Authorization': 'Bearer {0}'.format(access_token)}
url = 'https://upload.box.com/api/2.0/files/content'
#open(src_file,'rb') - opens the source file with the buffered reader
files = { 'filename': (box_filename, open(src_file,'rb')) }
data = { "parent_id": parent_id }
response = requests.post(url, data=data, files=files, headers=headers)
#file_info = response.json()
#print(file_info)
print(response)
print(url, data, files, headers)
counter = counter + 1
This is the sample curl request that the Box API documentation gives for downloading files.
curl -L https://api.box.com/2.0/files/FILE_ID/content \
-H "Authorization: Bearer ACCESS_TOKEN" \
-o FILE_PATH/file_name.txt
Part two of this question: Is there a way to alter this program (and the download program) to process all of the files within a folder no matter what the name of the file is?
I am new to programming, so please forgive my lack of skills/knowledge in this area.

Assume you are getting your authorization correct you can download file by adding few lines to code to your Existing code.
This will copy data from box file to local file here name is FileFromBox.xlx
with open('FileFromBox.xls', 'wb') as open_file:
client.file('FileId_of_box_file').download_to(open_file)
open_file.close()

I know this was asked long back, but still I believe many people are searching for the way to do it.
Please check Box SDK for more details.
And I'm using OAuth2.0 - Custom App. You can create the credentials from the developer console.
Here's the code.
from boxsdk import OAuth2, Client
#from boxsdk import Folder
auth = OAuth2(
client_id='fbxxxxxxxxxxxxxxxxxxxxxxxxxxxxx9',
client_secret='bPxxxxxxxxxxxxxxxxxxxxxxxxx4Or',
access_token='QExxxxxxxxxxxxxxxxxxxxxxxxxxwt',
)
client = Client(auth)
root_folder = client.root_folder().get()
items = root_folder.get_items()
for item in items:
print('{0} {1} is named "{2}"'.format(item.type.capitalize(), item.id, item.name))
with open(item.name, 'wb') as open_file:
client.file(item.id).download_to(open_file)
open_file.close()
Hope this will help you. Thanks to the Python boxsdk 2.0.0 Doc.

I would suggest you looking at Box SDK
As you can see in their docs, after authenticating with your client you only need to run the following line:
client.file(file_id='SOME_FILE_ID').content()
There is more information in Box SDK Docs. If this does not satisfy your necessities because you want to create your own Box SDK, then please wait for another person to give an specific response to your problem. Thanks.

You can download a file & folders into a zip like below:
name = 'test'
file = mock_client.file('466239504569')
folder = mock_client.folder('466239504580')
items = [file, folder]
output_file = open('test.zip', 'wb')
status = client.download_zip(name, items, output_file)
print('The status of the zip download is {0}'.format(status['state']))

Related

How to filter filenames with extension on API call?

I was working on the python confluence API for downloading attachment from confluence page, I need to download only files with .mpp extension. Tried with glob and direct parameters but didnt work.
Here is my code:
file_name = glob.glob("*.mpp")
attachments_container = confluence.get_attachments_from_content(page_id=33110, start=0, limit=1,filename=file_name)
print(attachments_container)
attachments = attachments_container['results']
for attachment in attachments:
fname = attachment['title']
download_link = confluence.url + attachment['_links']['download']
r = requests.get(download_link, auth = HTTPBasicAuth(confluence.username,confluence.password))
if r.status_code == 200:
if not os.path.exists('phoenix'):
os.makedirs('phoenix')
fname = ".\\phoenix\\" +fname
glob.glob() operates on your local folder. So you can't use that as a filter for get_attachments_from_content(). Also, don't specify a limit of since that gets you just one/the first attachment. Specify a high limit or whatever default will include all of them. (You may have to paginate results.)
However, you can exclude the files you don't want by checking the title of each attachment before you download it, which you have as fname = attachment['title'].
attachments_container = confluence.get_attachments_from_content(page_id=33110, limit=1000)
attachments = attachments_container['results']
for attachment in attachments:
fname = attachment['title']
if not fname.lower().endswith('.mpp'):
# skip file if it's not got that extension
continue
download_link = ...
# rest of your code here
Also, your code looks like a copy-paste from this answer but you've changed the actual "downloading" part of it. So if your next StackOverflow question is going to be "how to download a file from confluence", use that answer's code.

How can I use Python to download Qualtrics Survey responses via the Qualtrics API

Overview
I have found some Python code online which should allow me to download Qualtrics survey responses, however, there are aspects of the code which I would like to change for my specific needs. Unfortunately, I can't get it to work without breaking everything. The full code is included at the bottom.
My goals are as follows -
Connect to Qualtrics via the API and begin downloading a specific surveys responses
Display the download percentage with a maximum of 1 decimal place, as it downloads
Save the downloaded file as a .csv (zipped)
Current issues faced
The code already displays the download percentage, however, there are a crazy number of decimal places. I have tried rounding the value and then converting it to a string, which seems to work most of the time but occasionally the download percentage starts at something > 0 (no idea why, perhaps unrelated to round/converting)
print("Download is " + str(round(requestCheckProgress)) + " complete")
The code I found online will try to extract the .csv file once it has downloaded. This is NOT what I want, as I plan to email the .csv to someone once it's downloaded (it will be too large to email once extracted). Unfortunately, I don't know how to just save the file somewhere
I want to save the file to the users (not necessarily me) downloads folder
The full code is below, thanks for any help you can -
import requests
import zipfile
import json
import io
import os
# Setting user Parameters
apiToken = "" #I will replace this
surveyId = "" #I will replace this
fileFormat = "csv"
dataCenter = "" #I will replace this
# Setting static parameters
requestCheckProgress = int(0)
progressStatus = "in progress"
baseUrl = "https://{0}.qualtrics.com/API/v3/responseexports/".format(dataCenter)
headers = {
"content-type": "application/json",
"x-api-token": apiToken,
}
# Step 1: Creating Data Export
downloadRequestUrl = baseUrl
downloadRequestPayload = '{"format":"' + fileFormat + '","surveyId":"' + surveyId + '"}'
downloadRequestResponse = requests.request("POST", downloadRequestUrl, data=downloadRequestPayload, headers=headers)
progressId = downloadRequestResponse.json()["result"]["id"]
print(downloadRequestResponse.text)
# Step 2: Checking on Data Export Progress and waiting until export is ready
while requestCheckProgress < 100 and progressStatus != "complete":
requestCheckUrl = baseUrl + progressId
requestCheckResponse = requests.request("GET", requestCheckUrl, headers=headers)
requestCheckProgress = requestCheckResponse.json()["result"]["percentComplete"]
print("Download is " + str(round(requestCheckProgress)) + " complete")
# Step 3: Downloading file
requestDownloadUrl = baseUrl + progressId + '/file'
requestDownload = requests.request("GET", requestDownloadUrl, headers=headers, stream=True)
# Step 4: Unzipping the file
zipfile.ZipFile(io.BytesIO(requestDownload.content)).extractall(mypath + "/MyQualtricsDownload")
print('Complete')
So, to download to a specific folder, you should replace the '(mypath + "/MyQualtricsDownload")' with your desired folder location, e.g. 'C:\user\myname'.
Here is more information on the zipfile package: ZipFile for Python 3

How can i make this code (Google StreetView) work? I'm getting 403 forbidden messages everytime, even tho i set up a user agent

So I'm trying out a program which downloads google street view images. The addresses are located in a .txt file. Every time i try to run the code, the HTTP Error 403: Forbidden comes up. In my actual code, i use my Google Developer API of course, and the right file paths.
I've tried to set up a user agent, but it just doesn't work. Can anyone help me, what should i do? And how do i implement it in this code?
# import os and urllib modules
# os for file path creation
# urllib for accessing web content
import urllib
import os
import requests
# this is the first part of the streetview, url up to the address, this url will return a 600x600px image
pre = "https://maps.googleapis.com/maps/api/streetview?size=600x600&location="
# this is the second part of the streetview url, the text variable below, includes the path to a text file containing one address per line
# the addresses in this text file will complete the URL needed to return a streetview image and provide the filename of each streetview image
text = r"C:\Users\.............
# this is the third part of the url, needed after the address
# this is my API key, please replace the one below with your own (google 'google streetview api key'), thanks!
suf = "&key=abcdertghjhrtrwhgrh"
# this is the directory that will store the streetview images
# this directory will be created if not present
dir = r"C:\Users\..........
headers = {'User-Agent': 'Chrome/75.0.3770.100 Safari/537.36',
'From': 'asdasd#asd.com'
}
# checks if the dir variable (output path) above exists and creates it if it does not
if not os.path.exists(dir):
os.makedirs(dir)
# opens the address list text file (from the 'text' variable defined above) in read mode ("r")
with open(text, "r") as text_file:
# the variable 'lines' below creates a list of each address line in the source 'text' file
lines = [line.rstrip('\n') for line in open(text)]
print
"THE CONTENTS OF THE TEXT FILE:\n" + str(lines)
# start a loop through the 'lines' list
for line in lines:
# string clean-up to get rid of commas in the url and filename
ln = line.replace(",", "")
print
"CLEANED UP ADDRESS LINE:\n" + ln
# creates the url that will be passed to the url reader, this creates the full, valid, url that will return a google streetview image for each address in the address text file
URL = pre + ln + suf
response = requests.get(URL, headers = headers)
"URL FOR STREETVIEW IMAGE:\n" + URL
# creates the filename needed to save each address's streetview image locally
filename = os.path.join(dir, ln + ".jpg")
print
"OUTPUT FILENAME:\n" + filename
# you can run this up to this line in the python command line to see what each step does
# final step, fetches and saves the streetview image for each address using the url created in the previous steps
urllib.urlretrieve(URL, filename)

Downloading XML files from a web services URL in python

Please correct me if I am wrong as I am a beginner in python.
I have a web services URL which contains an XML file:
http://abc.tch.xyz.edu:000/patientlabtests/id/1345
I have a list of values and I want to append each value in that list to the URL and download file for each value and the name of the downloaded file should be the same to the value appended from the list.
It is possible to download one file at a time but I have 1000's of values in the list and I was trying to write a function with a for loop and I am stuck.
x = [ 1345, 7890, 4729]
for i in x :
url = http://abc.tch.xyz.edu:000/patientlabresults/id/{}.format(i)
response = requests.get(url2)
****** Missing part of the code ********
with open('.xml', 'wb') as file:
file.write(response.content)
file.close()
The files downloaded from URL should be like
"1345patientlabresults.xml"
"7890patientlabresults.xml"
"4729patientlabresults.xml"
I know there is a part of the code which is missing and I am unable to fill in that missing part. I would really appreciate if anyone can help me with this.
Accessing your web service url seem not to be working. Check this.
import requests
x = [ 1345, 7890, 4729]
for i in x :
url2 = "http://abc.tch.xyz.edu:000/patientlabresults/id/"
response = requests.get(url2+str(i)) # i must be converted to a string
Note: When you use 'with' to open a file, you do not have close the file since it will closed automatically.
with open(filename, mode) as file:
file.write(data)
Since the Url you provide is not working, I am going to use a different url. And I hope you get the idea and how to write to a file using the custom name
import requests
categories = ['fruit', 'car', 'dog']
for category in categories :
url = "https://icanhazdadjoke.com/search?term="
response = requests.get(url + category)
file_name = category + "_JOKES_2018" #Files will be saved as fruit_JOKES_2018
r = requests.get(url + category)
data = r.status_code #Storing the status code in 'data' variable
with open(file_name+".txt", 'w+') as f:
f.write(str(data)) # Writing the status code of each url in the file
After running this code, the status codes will be written in each of the files. And the file will also be named as follows:
car_JOKES_2018.txt
dog_JOKES_2018.txt
fruit_JOKES_2018.txt
I hope this gives you an understanding of how to name the files and write into the files.
I think you just want to create a path using str.format as you (almost) are for the URL. maybe something like the following
import os.path
x = [ 1345, 7890, 4729]
for i in x:
path = '1345patientlabresults.xml'.format(i)
# ignore this file if we've already got it
if os.path.exists(path):
continue
# try and get the file, throwing an exception on failure
url = 'http://abc.tch.xyz.edu:000/patientlabresults/id/{}'.format(i)
res = requests.get(url)
res.raise_for_status()
# write the successful file out
with open(path, 'w') as fd:
fd.write(res.content)
I've added some error handling and better behaviour on retry

Google Picker and download the selected file

I have managed to integrate the google Picker. Now I have the FileId and the access_token. I need to download the selected file in my back end which is in Python.
I have followed the documentation on google developers but If i use the python library then i have to authenticate the user again which is not suitable in my case.
Please enlighten me if I can download the file with any format.
Thanks in advance.
This is a very simple sample script for downloading files using access token and file id without Google library. And this sample supposes files (images and videos) except for Google Docs, as you said. The flow is as follows.
Flow :
Retrieve filename and mimeType.
Create filename from retrieved filename and mimeType. If the filename doesn't have the extension on Google Drive, this script adds the extension to the filename using mimeType and save it. If the filename has the extension on Google Drive, this script uses the original filename and save it.
Download a file and save it as the created filename. If you want to save the file to the specific directory, please set it by yourself.
Sample script :
import mimetypes
import os.path
import requests
accessToken = "### access token ###"
fileId = "### file id ###"
fileInf = requests.get(
"https://www.googleapis.com/drive/v3/files/" + fileId,
headers={"Authorization": "Bearer " + accessToken},
)
filename = fileInf.json()["name"]
temp, ext = os.path.splitext(filename)
filename = filename if ext != "" else filename + mimetypes.guess_extension(fileInf.json()["mimeType"])
r = requests.get(
"https://www.googleapis.com/drive/v3/files/" + fileId + "?alt=media",
headers={"Authorization": "Bearer " + accessToken},
)
with open(filename, "wb") as f:
f.write(r.content)
If this was not helpful for you, I'm sorry.

Categories