How do I send an attachment through REST response using Python Flask - python

I'm building a REST API, and it has to send a file in the response. I do not want to include the file content in the response body. Can we attach files to response ?

If I understood you right, you want to send a file with Content-Disposition header set to 'attachment'. Which instructs the browser to download/save the file, instead of displaying its contents inline on the page.
If that's what you want, then you'll have to do something like this:
from flask import make_response
#app.route('/txt')
def attachment():
resp = make_response('my text file')
resp.headers['Content-Type'] = 'text/plain;charset=UTF-8'
resp.headers['Content-Disposition'] = 'attachment;filename=SmartFileName.txt'
return resp

Related

Telegram Bot SendDocument pdf

I am having a real headache with the way of sending a pdf file to a Telegram Bot.
Apparently I am following the documentation but never get it sent.
I am using the url: https://api.telegram.org/botBOTID/sendDocument?chat_id=CHATID&document=/home/lix/Downloads/2.pdf
It is a pdf file storaged locally, but I think it is just the way I am presenting it.
The error getting is:
{"ok":false,"error_code":400,"description":"Bad Request: URL host is empty"}
Does anybody knows how to send a pdf local file?
Many thanks
You should send a POST request, with the PDF as a payload, using the Python Requests library, your code should look something like this:
import requests
# Url with bot token + user id
url = "https://api.telegram.org/bot<MY-BOT-TOKEN>/sendDocument?chat_id=<MY_CHAT_ID>"
# Create payload with PDF file
payload = {}
files = [
('document', open('/home/lix/Downloads/2.pdf','rb'))
]
headers= {}
# Request
response = requests.request("POST", url, headers=headers, data = payload, files = files)
# Log reponse as UTF-8
print(response.text.encode('utf8'))

How python flask server send back response with XML file

I coded a mock server, after I got a POST message with XML file, I need send back a response message with XML file also.
I found some example as below to send back response with XML content. But I think it's not a file. Anyone has idea on sending back response with a file?
result = open('output.xml', 'r').read()
r = Response(response=result, status=200, mimetype="application/xml")

Uploading an image from python client to a flask server

I am using requests and requests_toolbelt to send an image to the cloud and so far I have something like this
import requests
import json
from requests_toolbelt import MultipartEncoder
m = MultipartEncoder(
fields={"user_name":"tom", "password":"tom", "method":"login",
"location":"landing", "cam_id":"c00001", "datetime":"hammaTime!"
,'image': ('filename', open('image.jpg', 'rb'))}
)
r = requests.post(url, data=m)
print r.text
After it gets to the server, how to I get back a dictionary of something usable? The toolbelt docs show only how to post, not how to handle it on the other end. Any advice?
You can see a working example of Flask server which accepts POSTS like the on you're trying to make on HTTPbin. If you do something like:
m = MultipartEncoder(fields=your_fields)
r = requests.post('https://httpbin.org/post', data=m, headers={'Content-Type': m.content_type})
print(r.json()['form'])
You'll see that everything in your post should be in that dictionary.
Using HTTPBin's source, you can then see that the form section is generated from request.form. You can use that to retrieve the rest of your data. Then you can use request.files to access the image you wish to upload.
The example Flask route handler would look like:
#app.route('/upload', methods=['POST'])
def upload_files():
resp = flask.make_response()
if authenticate_user(request.form):
request.files['image'].save('path/to/file.jpg')
resp.status_code = 204
else:
resp.status_code = 411
return resp
You should read into Uploading Files documentation though. It is really invaluable when using common patterns like this in Flask.
requests-toolbelt can only send the file to the server but it is up to you to save that on the server side and then return meaningful result. You can create a flask endpoint to handle the file upload, return the desired result dictionary as a JSON and then convert the JSON back to dict on the client side with json.loads.
#app.route('/upload', methods=['POST'])
def upload_file():
if request.method == 'POST':
f = request.files['image']
f.save('uploads/uploaded_file')
# do other stuff with values in request.form
# and return desired output in JSON format
return jsonify({'success': True})
See flask documentation for more info on file uploading.
Also, you need to specify the mime-type while including the image in MultipartEncoder and content-type in the header while making the request. (I'm not sure you if you can even upload images with MultipartEncoder. I was successful with only the text files.)
m = MultipartEncoder(
fields={"user_name":"tom", "password":"tom", "method":"login",
"location":"landing", "cam_id":"c00001", "datetime":"hammaTime!"
,'image': ('filename', open('file.txt', 'rb'), 'text/plain')} # added mime-type here
)
r = requests.post(url, data=m, headers={'Content-Type': m.content_type}) # added content-type header here

how to return an excel sheet and a string response using httpresponse Django Python

I am currently returning a response page as a string but I also want to pass it as an excel file. I am having trouble doing both.
This is my views.py file:
response = HttpResponse(htmlString)
response = HttpResponse(mimetype='application/vnd.ms-excel')
response['Content-Disposition'] = 'attachment; filename=example1.xls'
book.save(response)
return response
This only gives me the excel file and not the HtmlString which is because I am reassigning response but I dont know how to include both paramaters.
THanks in advance!!
A HTTP response (as in the HTTP protocol, this is not limited to Django) will be treated by the browser either as a file, or displayed in the browser (html, plain text, etc). You cannot return a response with both.

How to set file name in response

I know about content-disposition but I read what it uses for email messages. And I want to know how I can set file name with content-type.
ps I use Pyramid framework
edit:
Web site has button 'download' how to perform Response object for file name too, like
return Response(body=f.read(), content_type='application/octet-stream')
and what I need to do for showing correct file name in browser.
You need to set the filename parameter of the Content-Disposition header like so:
response.content_disposition = 'attachment; filename="my_filename.txt"'
Use f string in python like below:
response = HttpResponse(file_data, content_type='application/pdf')
response['Content-Disposition'] = f'attachment; filename="{filename}"'
return response

Categories

Resources