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!
Related
I'm struggling with the datatables reordering. I want when user reorder to update table in the database. For this to happen i need:
to configure the datatable to send request to the server.
send the information about reordered datatable to flask endpoint.
Process data on the backend and update database table.
I have read the documentation but it is not clear to me.
My code:
$(document).ready(function () {
var dt = $('#data').DataTable({
rowReorder: true,
dom: 'Bfrtip'
});
});
My own solution:
JavaScript code:
dt.on('row-reorder.dt', function (e, details, edit) {
var slownik = {};
for (var i = 0, ien = details.length; i < ien; i++) {
let id_asortymentu = details[i].node.id;
let nowa_pozycja = details[i].newPosition+1;
console.log(id_asortymentu);
console.log(nowa_pozycja);
slownik[id_asortymentu] = nowa_pozycja;
}
req = $.ajax({
url: 'asortymenty/tabela_reorder',
dataType: "json",
type: 'POST',
data : JSON.stringify(slownik)
});
req.done(function(data){
if (data.result == 1){
console.log('Table reordered.');
}
});
});
Flask backend code:
#admin.route('asortymenty/tabela_reorder', methods = ['GET','POST'])
def table_reorder():
slownik=request.get_json('data')
for key, value in slownik.items():
asort = Asortyment.query.get(key)
print(asort.pozycja)
asort.pozycja = value
db.session.add(asort)
db.session.commit()
return jsonify({'result' : '1'})
I have a model that references other models, I am trying to save data using ajax
Example:
class Friend(models.Model):
name = ...
class Main(models.Model):
name = ....
friend = models.ForeignKey(Friend, on_delete=models.CASCADE)
All body comes from ajax(fetch) request
I have a table (html), and add data to cells, then with the
enter event, send data.
Like this:
input.addEventListener("keyup", function (e) {
//in this scenario I already have the whole row
// get full_row `row_data`
post_ajax = {
method: "POST",
headers: {
"X-CSRFToken": crf_token, // I get it with a regular expression
"Content-Type": "application/json",
"X-Requested-With": "XMLHttpRequest",
Accept: "application/json",
},
body: JSON.stringify(row_data),
};
fetch("my_url", post_ajax)
.then((res) => res.json())
.catch((error) => console.error("Error:", error))
.then((response) => console.log("Success:", response));
});
My view function
def save_post(request):
if request.is_ajax and request.method == "POST":
body_unicode = request.body.decode('utf-8')
data = json.loads(body_unicode)
print('here the data arrives',data)
# here the data arrives {'name': 'Ale', 'friend_id': 22}
Main.objects.create(name=data['name'], friends=data['friend_id'])
return JsonResponse({"instance": data}, status=200)
return JsonResponse({"error": ""}, status=400)
This is the error
raise TypeError("%s() got an unexpected keyword argument '%s'" %
(cls.__name__, kwarg))
TypeError: Main() got an unexpected keyword argument 'Friends'
Any idea or suggestion?
EDIT:
When you are creating the Main object, try making the "friend" attribute an object, like this:
friend = Friend.objects.get(id=data['friend_id'])
Main.objects.create(name=data['name'], friend=friend)
Also, the main issue appears to be you are calling the column "friends" but it should be "friend" when you are creating the Main object.
This:
Main.objects.create(name=data['name'], friends=data['friend_id'])
Should be:
Main.objects.create(name=data['name'], friend=data['friend_id'])
PREVIOUS ANSWER:
Assuming you are using JQuery in the template to send an AJAX request, since you did not specify.
In your urls.py:
...
path('/api/post_friend/', post_friend_api, name="post_friend_api"),
...
In your template :
<script type="text/javascript">
$("#myBurron").click(function(){
var csrfToken = $( "input[name='csrfmiddlewaretoken']"); // assuming this is a form
var friend_name = $("#friend_name").val();
$.ajax({ url: '{% url 'post_friend_api' %}',
type: "POST",
dataType: "json",
data: {'friend':friend_name, 'csrfmiddlewaretoken':csrfToken.val()},
cache: false
}).done(function(data) {
if (data.result === true){
alert(data.message);
}
});
});
});
</script>
In your views.py:
from django.http import JsonResponse
def post_friend_api(request):
data = {}
if request.POST.get('friend', None) is not None:
friend_name = request.POST.get('post_note')
# save the object and indicate success
data['result'] = True
data['message'] = "Friend saved successfully"
...
if request.is_ajax():
return JsonResponse(data)
else:
return HttpResponseBadRequest()
When you are sending data via POST don't forget to pass along your CSRF token as in the example above. This assumes you have a form on the page you can get it from, otherwise you can use something like this to get it:
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie !== '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = cookies[i].trim();
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
var csrftoken = getCookie('csrftoken');
If you don't want to deal with the CSRF token, you can mark the view with the #csrf_exempt decorator and remove the 'csrfmiddlewaretoken' data element from the Ajax call in the template, but it may not be ideal or the most secure. An example of that:
from django.views.decorators.csrf import csrf_exempt
from django.http import JsonResponse
#csrf_exempt()
def post_note_api(request):
...
If you post more details I can update my answer.
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
I'm making a POST request from AngularJS to Python.
I started with an JavaScript example. It works properly returning all the values.
However, when I try to do it from AngularJS I'm not able to read the value of the variable posted.
JAVASCRIP EXAMPLE THAT WORKS PROPERLY (I'm able to get the value (Mike) back of Name):
JS code
<script language="Javascript">
function asyncChange()
{
var request;
if (window.XMLHttpRequest) {
request = new window.XMLHttpRequest();
} else {
// Versiones antiguas de Internet Explorer.
request = new window.ActiveXObject("Microsoft.XMLHTTP");
}
request.open("POST","nctest.py" , true);
request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
request.send("Name=Mike");
request.onreadystatechange = function()
{
if (request.readyState == 4 && request.status == 200)
{
document.getElementById("myLabel").innerHTML = "Hello " + request.responseText + "!";
}
}
}
</script>
nctest.py
#!/usr/bin/python
import cgi
input = cgi.FieldStorage()
print "Content-type: text/html\n\n"
print "input[Pe].value: "
print input["Pe"].value
ANGULARJS DOESN'T WORK PROPERLY (I'm not able to get the value (Mike) back of Name):
Angularjs code:
(function(){
'use strict'
var sectest= {
controller:sectestCtrl,
templateUrl:'app/components/component_test/test.html',
}
angular
.module('myapp')
.component('secTest',sectest);
function sectestCtrl($http){
var prac= this;
prac.method = 'POST';
prac.url = 'nctest.py';
prac.data = {Name : 'Mike'};
prac.data_answer
prac.headers = { 'Content-Type': 'application/x-www-form-urlencoded' };
prac.sendHTML = send;
function send(){
prac.code = null;
prac.response = null;
$http({method: prac.method, headers: prac.headers, url: prac.url, data: $.param(prac.data)}).
then(function(response) {
prac.status = response.status;
prac.data_answer = response.data;
console.log("OK prac.data_answer: ", prac.data_answer)
}, function(response) {
prac.data_answer = response.data || 'Request failed';
prac.status = response.status;
});
};
}
})();
nctest.py code
#!/usr/bin/python
import json
import cgi
input = cgi.FieldStorage()
print "Content-type: text/html\n\n"
print input["Name"].value
The problem is that prac.data_answer prints blank value.
I have already try with different headers for both angularjs and python codes but none seems to work:
prac.headers = { 'Content-Type': 'application/json' };
prac.headers = { 'Content-Type': 'application/x-www-form-urlencoded' };
prac.headers = { 'Content-Type': 'text/html\n\n' };
Many thanks.
There are 2 separate issues you're trying to address. Server (CGI) & client(angularjs). First check to see that you are receiving the data over the network - using Chrome developer tools, under the Network tab. If so, there's no need to change the Content-Type to json, since angular by default assumes all http data is in json format.
I don't think you need all those attributes for a post request. Seems like an overkiller when it can be simpler. Try this:
$http.post(url, data).then(function(response){
console.log(response.data);
});
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