Download CSV file to the client - python

I have the following route:
#app.route('/download/', methods=['GET'])
def download():
output_filename = request.args.get('output_filename')
data = dict(foos=[1,2,3,3,2,1], bars=[7,7,7,7,7,7])
df = pd.DataFrame(data)
result = df.to_csv(index=False)
response = make_response(result)
response.headers['Content-Disposition'] = f'attachment; filename={output_filename}'
response.headers['Cache-Control'] = 'must-revalidate'
response.headers['Pragma'] = 'must-revalidate'
response.headers['Content-type'] = 'application/csv'
return response
which I'm calling with AJAX as follows:
function download(data, handler = null) {
let data = {output_filename: "foo.csv"};
let url = "/download/";
$.ajax({
type: "GET",
url: url,
data: data,
success: function(data) {
console.log('success');
},
});
}
However, nothing's appearing on the client side. Am I missing something here?

Im more familiar with node than ajax ( i had the same issue in nodejs which i fixed here on stackoverflow), but maybe this will help:
$.ajax({
async: false,
from How do I make jQuery wait for an Ajax call to finish before it returns?

Related

Converting a JS Rest API Call into Python

I'm looking for assistance with translating a piece of sample code written in javascript into something that will work with Python. The sample code is for the 'POST Authenticate' Endpoint of CCH Axcess' Open Integration Kit, which sends a response containing a Security Token
URL: https://api.cchaxcess.com/api/AuthServiceHelp/v1.0/help/operations/Authenticate
Sample Code:
var _restIntegratorKey = "{User Integrator Key}"; // Please use this variable as global variable as all subsequent call required this integrator key to pass
var _restHostUrl = "{host url}"; // i.e. "{Protocol}://{host name}/api"
var request = $.ajax({
url: _restHostUrl + "/AuthService/v1.0/Authenticate",
contentType: "application/json; charset=utf-8",
type: "GET",
dataType: "json"
});
var request = {
UserName: "{username}", // Specify Username
UserSid: "anyone",
Password: "{password}", // Specify Password
Realm: "{accountnumber}" // Specify Account number
};
var request = $.ajax({
url: _restHostUrl + "/AuthService/v1.0/Authenticate",
data: JSON.stringify(request),
beforeSend: _setHttpHeader,
contentType: "application/json",
type: "POST",
dataType: "json"
});
request.done(function (data, textStatus, jqXHR) {
// This method block will be executed on succefull execution of api and will return security token.
// Below statement will store returned security token into browser cookie named: "CchNGAuthToken". you can use any other way to persist this token.
// This security token we required to pass in header for other rest api calls
document.cookie = "CchNGAuthToken=" + data.Token;
});
request.fail(function (jqXHR, textStatus, err) {
// This method block will be executed if API returns any error.
});
// Please keep these below two methods, As both will be used in subsequent call, to get SSOToken from Cookie
// set Security token and integratorkey into request header
function _setHttpHeader(xhr) {
var ssoToken = _getSessionCookie("CchNGAuthToken"); // Read security token from document cookie which we set during authentication rest api call
xhr.setRequestHeader("Security", ssoToken);
xhr.setRequestHeader("IntegratorKey", _restIntegratorKey);
};
// Get session cookie
function _getSessionCookie(name) {
var key = name + "=";
var cookie = "";
if (document.cookie.length > 0) {
var begin = document.cookie.indexOf(key)
if (begin != -1) {
begin += key.length
var end = document.cookie.indexOf(";", begin);
if (end == -1)
end = document.cookie.length;
cookie = unescape(document.cookie.substring(begin, end))
}
}
return cookie;
};
I have an LIC file with the IntegratorKey stored in XML format, like:
<?xml version="1.0"?>
<IntegratorInfo>
<IntegratorKey>XXXXX-XXX-XXX-XXXX</IntegratorKey>
</IntegratorInfo>
I think my primary issue is identifying the values of the 'ssoToken' and '_restIntegratorKey' variables once they're assigned inside the '_setHttpHeader' function.
My attempt:
def getcchauth():
import requests
integratorkey = getintkey()
cookie = getcookie()
authheaders = {
'Security': cookie,
'IntegratorKey': integratorkey,
'content-type': 'application/json; charset=utf-8'
}
cchlogin = {
'UserName':"user",
"UserSid": 'anyone',
'Password': 'password',
'Realm' : '123456',
}
authattempt = requests.post(resthosturl+endpoint, data = cchlogin,
headers=authheaders)
print(authattempt.headers)
def getcookie():
import requests
import json
cookieresponse = requests.get(resthosturl+apiservdir,
headers = headers)
cookieresponse = json.dumps(cookieresponse.headers.__dict__['_store'])
cookieresponse = json.loads(cookieresponse)
cookie = 'CchNGAuthToken=' + cookieresponse['set-cookie'][1].split(';')[0].strip() + ';'
print(cookie)
return cookie
Thanks!

Bad request Json to Flask ajax

My Jquery code:
var obj_submit = {
email_p : $($('.form-group').find("input[name='email_p']")[0]).val(),
email_a : $($('.form-group').find("input[name='email_a']")[0]).val()
}
var json_submit = JSON.stringify(obj_submit);
$.ajax({
type: 'GET',
url: url,
contentType: 'application/json',
dataType: 'json',
data: json_submit
My python code:
`#app.route('/admission', methods=["GET", "POST"])
def admission():
form = FormFieldsAdmissao()
print (request.is_json)
content = request.get_json()
print (content)
return 'JSON posted'`
in the browser console I receive: GET [...] 400 (BAD REQUEST)
(the number of questions on the same subject is impressive, it makes me think it was something that should be simpler, since everyone has questions about it)

Python string is null but also isn't None nor empty string

class StartAnalysis(BaseHandler):
def post(self):
playlist = self.request.get('playlist')
language = self.request.get('language')
If I make a POST request without this playlist field, then this happens:
>>> playlist
null
>>> type(playlist)
<type 'unicode'>
>>> playlist is None
False
>>> not playlist
False
>>> playlist == ''
False
>>> playlist == u''
False
How am I supposed to check that it's None? And why is it saying that it's null and not None?
I'm using AppEngine.
My javascript code making the POST request:
let params = new URLSearchParams(location.search);
let url_id = params.get('id');
let url_language = params.get('language');
const url = 'http://localhost:8080/start-analysis?playlist=' + url_id + '&language=' + url_language;
$.ajax({
url: url,
type: 'POST',
success: function(results) {
...
},
error: function(error) {
...
}
});
I changed to using application/json for the POST requests instead of the default application/x-www-form-urlencoded and that seemed to fix the problem of the request sending the string "null" instead of just an empty string when one of the parameters was empty or missing.
let params = new URLSearchParams(location.search);
let url_id = params.get('id');
let url_language = params.get('language');
const url = 'http://localhost:8080/start-analysis';
$.ajax({
url: url,
type: 'POST',
dataType: 'json',
contentType: 'application/json',
data: JSON.stringify({'playlist': url_id,'language': url_language}),
success: function(results) {
...
},
error: function(response, status, error) {
...
}
});
And the backend receives it like:
class StartAnalysis(BaseHandler):
def post(self):
data = json.loads(self.request.body)
playlist = data['playlist']
language = data['language']

How do a make a API request in Swift like the working Python request I'm currently using?

I'm looking to convert this Python request to a Swift script.
Here is my working python script that returns the accessToken!
#!/usr/bin/python
import requests
import json
#MAKE THE REQUEST
URL = "http://this/is/the/url"
headers = {
'Accept': "application/json",
"Accept-Language": "en_US"
}
data = {
"grant_type": "password",
"username" : "GROUP\SITE\USERNAME",
"password" : "somepassword"
}
r = requests.get(url = URL, params = headers, data = data)
data = r.json()
accessToken = data['access_token']
print(accessToken)
When I run the Swift Playground for the code below nothing is returned!
It seems the script exits at guard let data = data else { return }
How could I get the same results as the Python Script above.
I've tried implementing URLComponents using this tutorial...
import UIKit
var url = "http://just/the/url"
extension Dictionary {
func percentEncoded() -> Data? {
return map { key, value in
let escapedKey = "\(key)"
let escapedValue = "\(value)"
print(escapedKey + "=" + escapedValue)
return escapedKey + "=" + escapedValue
}
.joined(separator: "&")
.data(using: .utf8)
}
}
extension CharacterSet {
static let urlQueryValueAllowed: CharacterSet = {
let generalDelimitersToEncode = ":#[]#" // does not include "?" or "/" due to RFC 3986 - Section 3.4
let subDelimitersToEncode = "$&'()*+,;="
var allowed = CharacterSet.urlQueryAllowed
allowed.remove(charactersIn: "\(generalDelimitersToEncode)\(subDelimitersToEncode)")
return allowed
}()
}
var request = URLRequest(url: URL(string:url)!)
request.httpMethod = "GET"
let parameters: [String: String] = [
"grant_type":"password",
"username":"GROUP\\SITE\\USER",
"password":"somePassword"
]
request.httpBody = parameters.percentEncoded()
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.setValue("application/XML", forHTTPHeaderField: "Accept")
let config = URLSessionConfiguration.default
URLSession(configuration: config).dataTask(with: request) { (data, response, err) in
guard let data = data else { return }
print(data)
guard let dataAsString = String(data: data, encoding: .utf8)else {return}
print(dataAsString)
guard let httpResponse = response as? HTTPURLResponse,
(200...299).contains(httpResponse.statusCode) else {
print("Bad Credentials")
return
}
//HTTP Status Code!
print("HTTP RESPONSE:"+"\(httpResponse.statusCode)")
//
}.resume()
If I remember correctly, starting in iOS 13, you cant have httpBody for a GET call, so you'll either need to switch to a POST/PUT or add the params into the url string (See below)
You also had different Accept headers in your python vs. swift. One was xml the other was json.
var urlComponents = URLComponents(string: "http://this/is/the/url")
urlComponents?.queryItems = [
URLQueryItem(name: "grant_type", value: "password"),
URLQueryItem(name: "username", value: "username"),
URLQueryItem(name: "password", value: "somepassword")
]
guard let url = urlComponents?.url else { return } // You can print url here to see how it looks
var request = URLRequest(url: url)
request.httpMethod = "GET"
request.setValue("application/json", forHTTPHeaderField: "Accept")
request.setValue("en_US", forHTTPHeaderField: "Accept-Language")
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data,
let response = response as? HTTPURLResponse,
error == nil else {
print("error", error ?? "Unknown error")
return
}
print(response)
guard (200 ... 299) ~= response.statusCode else {
print("response = \(response)")
return
}
let responseString = String(data: data, encoding: .utf8)
print(responseString)
}
task.resume()
The problem was the following...
request.httpMethod = "GET"
I had to change the get to "POST" and now I have the token!!!!
I was confused because the python script used GET. I had a bash script that that used curl to get the token displayed the logged post.
In short my above Swift Playground now works by changing the request.httpMethod to "POST". THANKS FOR ALL THE HELP

AJAX/PYTHON : how to send json value to server

I am a new to Ajax/Python, I don't know how to POST a json value to my python server.
Python code:
#app.route('/ajouterContact', methods = ['POST'])
def ajouterContact():
data = json.loads(request.data)
#nom = request.form['nomContact'];
contact.append(data)
ajouter.make_response(json.dumps(contact), 201)
ajouter.headers['Content-Type'] = 'application/json'
JS code
$('#buttonAjouter').click(function() {
var nom = 'Tom';
var myObj = new Object();
myObj.nom = nom;
var jsonText = JSON.stringify(myObj);
var i = 0;
$.ajax({
url: '/ajouterContact',
data: jsonText,
type: 'POST',
dataType: "json",
success: function(response) {
console.log(response);
},
error: function(error) {
console.log(error);
}
});
});
I am getting this error on server side :
ValueError: No JSON object could be decoded
If anyone can help me on this..
Thank you!
You need to provide the contentType in your ajax request:
contentType: 'application/json;charset=UTF-8',
Then in your server try to debug something like this:
request.json

Categories