Python Flask Swagger Flasgger Download Excel - python

I am trying to return an excel file from Swagger API. Built that using Flask with a Swagger wrapper with Flasgger. Here's the code -
#app.route('/cluster', methods=['POST'])
def index():
"""
This API will help you generate clusters based on keywords present in unstructured text
Call this api passing the following parameters -
Dataset Path - <hostname>\\<path to dataset>
Column Name based on which clustering needs to be done
Number of Clusters
Sample URL: http://localhost:8180/cluster/clusters.csv?dataset=\\\\W1400368\\c$\\Users\\VK046010\\Documents\\Python%20Scripts\\RevCycle_PatientAcc.csv&ext=csv&col=SR_SUM_TXT&no_of_clusters=100
---
tags:
- Clustering API
parameters:
- name: dataset
in: formData
type: file
required: true
description: The fully qualified path of the dataset without the extension.
- name: col
in: query
type: string
required: true
description: The column name on which the clustering needs to be done
- name: no_of_clusters
in: query
type: integer
required: true
description: The number of clusters
"""
global data
data = data.fillna('NULL')
output = StringIO.StringIO()
data.to_csv(output,index=False)
resp = Response(output.getvalue(), mimetype="text/csv")
resp.headers["Accept"] = "text/csv"
resp.headers['Access-Control-Allow-Origin'] = '*'
resp.headers["Content-Disposition"] = "attachment; filename=clusters.csv"
return resp
This returns a downloadable link which I have to rename to csv to make it work.
Question: I am not being able to do this for excel files. No matter how I do it, once I download and rename, excel says the file is corrupt and that's that.
I tried pyexcel and pandas excel writer, didn't work out. Please help!

Try to use flasgger to download excel. You can change the response type to "application/octet-stream" to resolve it.

Did you try to change the mimetype?
I think that the traditional mimetype for excel is application/vnd.ms-excel
You could find more details on microsoft files mimetype here: What is a correct mime type for docx, pptx etc?

Related

Resource Not Found Error: When Reading CSV from Azure Blob using Pandas with its SAS URL

I am trying to perform Dataset versioning where I read a CSV file into a pandas DataFrame and then create a new version of an Azure ML Dataset. I am running the below code in an Azure CLI job within Azure DevOps.
df = pd.read_csv(blob_sas_url)
At this line, I get a 404 Error.
Error Message:
urllib.error.HTTPError: HTTP Error 404: The specified resource does not exist
I tried to do this locally, I was able to read the csv file into Dataframe.
The SAS URL and token are not expired too.
How to solve this issue?
Edit - Code
def __init__(self, args):
self.args = args
self.run = Run.get_context()
self.workspace = self.run.experiment.workspace
def get_Dataframe(self):
print(self.args.blob_sas_url)
df = pd.read_csv(self.args.blob_sas_url)
return df
def create_pipeline(self):
print("Creating Pipeline")
print(self.args.blob_sas_url)
dataframe = self.dataset_to_update()
# Rest of Code
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Azure ML Dataset Versioning pipeline')
parser.add_argument('--blob_sas_url', type=str, help='SAS URL to the Data File in Blob Storage')
args = parser.parse_args()
ds_versioner = Pipeline(args)
ds_versioner.create_pipeline()
In both the instances where I print the SAS URL within the script print(self.args.blob_sas_url), the URL is shortened. I was able to see this in the std_log.txt file.
The reason of shortening or technically trimming your input argument is that the bash variable is split at the & level. so all the rest of your sas url goes as "commands" or other "arguments". Apparently that is how azure parses it.
eg:
python3 test_input.py --blob_sas_url "somepath/to/storage/account/file.txt?sv=2022-01-01&sr=b&sig=SOmethingwd21dd1"
>>> output: somepath/to/storage/account/file.txt?sv=2022-01-01&sr=b&sig=SOmethingwd21dd1
python3 test_input.py --blob_sas_url somepath/to/storage/account/file.txt?sv=2022-01-01&sr=b&sig=SOmethingwd21dd1
>>> output:
[1] 1961
[2] 1962
[2]+ Done sr=b
so you just need to quote your Azure variable in your step command like follows:
python3 your_python_script.py --blob_sas_url "$(azml.sasURL)"

Getting values from XML Url Python

I have an account in https://es.besoccer.com/ and they have an api for getting data in a xml.
I have this code in python for print the values of the xml I need:
from xml.dom import minidom
doc = minidom.parse("datos.xml")
partidos = doc.getElementsByTagName("matches")
for partido in partidos:
local = partido.getElementsByTagName("local")[0]
visitante = partido.getElementsByTagName("visitor")[0]
print("local:%s" % local.firstChild.data)
print("visitante:%s" % visitante.firstChild.data)
canales=partido.getElementsByTagName("channels")
for canal in canales:
nombre=canal.getElementsByTagName("name")[0]
print("canal:%s" % nombre.firstChild.data)
The problem is thatthe XML of this site is a url so I donĀ“t know how to read the xml directly form the url. Other problem is that the xml contains some tags that are a link, and python throughs a error with that tags that contains a url.
Read the API docs here: https://www.besoccer.com/api/documentacion
After you understand which API call you need to use, prepare the URL and the query arguments and use a library like requests in order to read the data.
Once you have the reply (assuming it is XML based) - you can use your code and parse it.

Create a task with attachments in Asana using Asana api

I am trying to send an image using Asana's API but it just attaches a blank file.
This is the code I have been using.
client.attachments.create_on_task(task_id=123456789,file_content="Url_of_file",file_name='Name_of_File',file_content_type="image/jpeg")
I have tried using different file formats like .txt and .png but for some reason the Asana API is blocking my requests.It just posts a black image on Asana.
I have tried to convert the file to base64 as well but it still doesn't work
In this original documentation(below), it shows that we need to pass two arguments;one for the file's content and the other for file itself ('file').
def create_on_task(self, task_id, file_content, file_name, file_content_type=None, **options):
"""Upload an attachment for a task. Accepts a file object or string, file name, and optional file Content-Type"""
path = '/tasks/%d/attachments' % (task_id)
return self.client.request('post', path, files=[('file', (file_name, file_content, file_content_type))], **options)
But when I am trying to pass the arguments for file and file content it shows me an error.
Can somebody please help me with this?
Another user on the Asana development forum had the same problem using the Curl API. (https://forum.asana.com/t/sending-file-with-api/16897/2). Apparently it has something to do with the 'multipart form upload'.
Looking through another thread here on stackoverflow (How to send a "multipart/form-data" with requests in python?), it seemed the file object had to be read in binary was all.
so the parameters would be:
client.attachments.create_on_task(task_id=<task id here>,file_content=open(filename_with_path, 'rb'),file_name='Name_of_File',file_content_type="image/jpeg")

How do I use python requests to download a processed files?

I'm using Django 1.8.1 with Python 3.4 and i'm trying to use requests to download a processed file. The following code works perfect for a normal request.get command to download the exact file at the server location, or unprocessed file.
The file needs to get processed based on the passed data (shown below as "data"). This data will need to get passed into the Django backend, and based off the text pass variables to run an internal program from the server and output .gcode instead .stl filetype.
python file.
import requests, os, json
SERVER='http://localhost:8000'
authuser = 'admin#google.com'
authpass = 'passwords'
#data not implimented
##############################################
data = {FirstName:Steve,Lastname:Escovar}
############################################
category = requests.get(SERVER + '/media/uploads/9128342/141303729.stl', auth=(authuser, authpass))
#download to path file
path = "/home/bradman/Downloads/requestdata/newfile.stl"
if category.status_code == 200:
with open(path, 'wb') as f:
for chunk in category:
f.write(chunk)
I'm very confused about this, but I think the best course of action is to pass the data along with request.get, and somehow make some function to grab them inside my views.py for Django. Anyone have any ideas?
To use data in request you can do
get( ... , params=data)
(and you get data as parameters in url)
or
post( ... , data=data).
(and you send data in body - like HTML form)
BTW. some APIs need params= and data= in one request of GET or POST to send all needed information.
Read requests documentation

Use put_internal to upload file using python eve

I want to store media files on certain mongo documents.
I was thinking of using eve's put_internal method call to update the document.
How would I use the payload param to provide the file as payload ?
You want to provide the file value as a FileStorage object. So suppose your media field is called media, a hypothetical payload would look like:
{'media': <FileStorage: u'example.jpg' ('image/jpeg')>, ...}
In order to achieve that you would do something like:
from werkzeug import FileStorage
f = open('example.jpg','r')
fs = FileStorage(f)
payload['media'] = fs

Categories