Download file from API server - python

I need to upload a file to the system from the API server. post method, the server accepts an authorization token and a file id. I tried to do this by writing to a file(.write(responce.content)), but the text of the saved file is: "Unable to get a response from the server."
code:
import requests
def test_download():
headers = {"Authorization": "token"}
data = {"fileId": "43232-31621-51923-31515-59031"}
responce = requests.post("url/api/integration/file/download",
headers=headers, json=data)
with open("download_file.txt", "wb") as code: code.write(responce.content)
print(responce.text)
assert responce.status_code == 200
but I need the text of the file from the server. is it possible to download the file in another way? thank you in advance)

Related

How to upload the file in POST requests (form-data)?

I use this GET request https://api.telegram.org/file/bot<token>/<file_path> which allow us to download the file from Telegram API.
Now I need to send this file in the second POST request (form-data).
Right now my code raises such error:
Exception: embedded null byte Traceback
The code snippet:
# Download the file via GET request of the Telegram API.
response = requests.get("{0}/file/bot{1}/{2}".format(TELEGRAM_API_URL, telegram_bot_token, file_path))
files = [
('file', (file_name, open(response.content, 'rb'), 'application/octet-stream')) # error
]
# Upload the file via POST request.
response = requests.post(FILE_STORAGE_SERVICE_API_URL, files=files)
Question:
How do I convert a file correctly so that a POST request can process it?
The data type of the response.content which I take from the first request is <class 'bytes'>.
The working code snippet:
response = requests.get("{0}/file/bot{1}/{2}".format(TELEGRAM_API_URL, telegram_bot_token, file_path))
files = {
"file": response.content
}
requests.post(FILE_STORAGE_SERVICE_API_URL, files=files)

Uploading and uploaded file without saving with python requests

I have a web server that acts as a proxy between users and a file server. Users can upload their files to my web server and I upload them to the file server. I want to be able to do this without saving the temp uploaded file but every time I get unexpected end of file error from the file server. This is my code (I'm using django rest framework for my APIs).
headers = {"content-type":"multipart/form; boundary={}".format(uuid.uuid4().hex)}
files = []
for f in request.FILES.getlist('file'):
files.append((f.name, open(f.file.name,'rb'), f.content_type))
files_dict = {'file': files}
r = requests.post(url, files=files, headers=headers)
You are misusing the content-type header in your request. There is no need to manually set multipart/form and boundary if you're using files argument from requests. That is why you're getting unexpected end of file error. Try sending your request without that header.
r = requests.post(url, files=files)

Download file from internet and serve to website using Django without exposing URL

I am downloading an audio file using some URL get request. I cannot expose the URL, as it contains an API-key. What is the right way to serve this file to a website?
Make a view where you download the file and then serve back the file in a response to your frontend.
Here is the Django docs showing you how to stream a file as a response using a generator.
import requests
from django.http import StreamingHttpResponse
def stream_audio(request):
file_url = "your.url.com"
r = requests.get(file_url, stream=True)
response = StreamingHttpResponse(streaming_content=r, content_type='audio/mpeg')
response['Content-Disposition'] = 'attachment; filename="somefilename.mp3"'
return response
This way you never expose your API key but you can send the same information to the user.

Send Presentation object as http response for download.

I am trying to develop a flask server which generates a presentation object based on json data and files from a HTTP Post request.
I am able to generate the file locally with same code but when I try to send it as an http response is fails.
Here is the code snippet for sending it as an http response -
prs_file_io = BytesIO()
prs.save(prs_file_io)
resp = Response()
resp.status_code = 200
resp.set_data(prs_file_io.getvalue())
return resp
And here is the python script sending the request and trying to save the file -
r = requests.post('http://localhost:8181/create-ppt',
#data=open('tile_resp.json', 'rb'),
files={'1': open('./0NtNFb0F9ch15fDrgYoECEpctPkjvayD.png', 'rb'),
'tile_data': open('tile_resp.json', 'rb')})
print(r.content)
And finally I pipe the output from request script to a pptx file.
But this is not working any idea what mistake I am making here?
How about the following:
response = make_response(prs_file_io.get_value())
response.headers['Content-Type'] = "application/vnd.openxmlformats-officedocument.presentationml.presentation"
response.headers['Content-Description'] = 'attachment; filename=example.pptx'
return response
make_response is a method from Flask see make_response()
Would that work if the response should be a pptx file?
I do this using
send_file
By doing:
from flask import send_file
from app import application
from pptx import Presentation
import os
prs=Presentation()
filename = os.path.join(application.root_path, 'test.pptx')
prs.save(filename)
return send_file(filename_or_fp=filename)
In my code, the application is defined in a python file in the app folder, hence the line:
from app import application
You'll have to change this for your application if you want to go this route.
This is an old question but none of the above worked for me, so I want to share my solution:
prs = Presentation(input)
file = io.BytesIO()
prs.save(file)
response = HttpResponse(content_type='application/vnd.ms-powerpoint')
response['Content-Disposition'] = 'attachment; filename="sample.pptx"'
response.write(file.getvalue())
file.close()
return response

ServiceNow - How to use SOAP to download reports

I need to automate download of reports from serviceNow.
I've been able to automate it using python and selenium and win32com by following method.
https://test.service-now.com/sys_report_template.do?CSV&jvar_report_id=92a....7aa
And using selenium to access serviceNow as well as modify firefox default download option to dump the file to a folder on windows machine.
However, Since all of this may be ported to a linux server , we would like to port it to SOAP or CURL.
I came across serviceNow libraries for python here.
I tried it out and following code is working if I set login , password and instance-name as listed at the site using following from ServiceNow.py
class Change(Base):
__table__ = 'change_request.do'
and following within clientside script as listed on site.
# Fetch changes updated on the last 5 minutes
changes = chg.last_updated(minutes=5)
#print changes client side script.
for eachline in changes:
print eachline
However, When I replace URL with sys_report_template.do, I am getting error
Traceback (most recent call last):
File "C:\Python27\lib\site-packages\SOAPpy\Parser.py", line 1080, in _parseSOAP
parser.parse(inpsrc)
File "C:\Python27\Lib\xml\sax\expatreader.py", line 107, in parse
xmlreader.IncrementalParser.parse(self, source)
File "C:\Python27\Lib\xml\sax\xmlreader.py", line 125, in parse
self.close()
File "C:\Python27\Lib\xml\sax\expatreader.py", line 220, in close
self.feed("", isFinal = 1)
File "C:\Python27\Lib\xml\sax\expatreader.py", line 214, in feed
self._err_handler.fatalError(exc)
File "C:\Python27\Lib\xml\sax\handler.py", line 38, in fatalError
raise exception
SAXParseException: <unknown>:1:0: no element found
Here is relevent code
from servicenow import ServiceNow
from servicenow import Connection
from servicenow.drivers import SOAP
# For SOAP connection
conn = SOAP.Auth(username='abc', password='def', instance='test')
rpt = ServiceNow.Base(conn)
rpt.__table__ = "sys_report_template.do?CSV"
#jvar_report_id replaced with .... to protect confidentiality
report = rpt.fetch_one({'jvar_report_id': '92a6760a......aas'})
for eachline in report:
print eachline
So, my question is , what can be done to make this work?
I looked on web for resources and help, but didn't find any.
Any help is appreciated.
After much research I was able to use following method to get report in csv format from servicenow. I thought I will post over here in case anyone else runs into similar issue.
import requests
import json
# Set the request parameters
url= 'https://myinstance.service-now.com/sys_report_template.do?CSV&jvar_report_id=929xxxxxxxxxxxxxxxxxxxx0c755'
user = 'my_username'
pwd = 'my_password'
# Set proper headers
headers = {"Accept":"application/json"}
# Do the HTTP request
response = requests.get(url, auth=(user, pwd), headers=headers )
response.raise_for_status()
print response.text
response.text now has report in csv format.
I need to next figure out, how to parse the response object to extract csv data in correct format.
Once done, I will post over here. But for now this answers my question.
I tried this and its working as expected.
`import requests
import json
url= 'https://myinstance.service-now.com/sys_report_template.do?CSV&jvar_report_id=929xxxxxxxxxxxxxxxxxxxx0c755'
user = 'my_username'
pwd = 'my_password'
response = requests.get(url, auth=(user, pwd), headers=headers )
file_name = "abc.csv"
with open(file_name, 'wb') as out_file:
out_file.write(response.content)
del response`

Categories