Sending True/False from python api call - javascript

i dont know if this is a stupid question but ive made a script that is making a api put call using requests in python. The data im trying to send contains a boolean value. So i have my script like this
import requests
data = {
'name': 'John',
'lastname': "Doe",
'email': "jd#gmail.com",
'is_staff' : True
}
url = 'http://api.url/user/'
response = requests.put(
url, data=data, verify=True, allow_redirects=False)
print(response)
But this gives me a 400 request error.
Then i thought that the problem was with the api call but when i remove the is_staff data.
data = {
'name': 'John',
'lastname': "Doe",
'email': "jd#gmail.com",
}
I get a 200 status code. My inutution is telling me that the api doesnt know what the boolean value from python is. But i could be wrong. Any ideas?

You need to JSON encode your string or rather 'serialize'.
Serialize obj to a JSON formatted str using this conversion table. If ensure_ascii is false, the result may contain non-ASCII characters and the return value may be a unicode instance.
Source
import requests
import json
data = {
'name': 'John',
'lastname': "Doe",
'email': "jd#gmail.com",
'is_staff' : True
}
url = 'http://api.url/user/'
headers = {'content-type': 'application/json'}
response = requests.put(url, data=json.dumps(data), headers=headers, verify=True, allow_redirects=False)
print(response)

The requests library takes the data dict and turns it into the request body, the request body is not a dict but a string containing the keys and values. In this case it turns it into the key1=value1&key2=value2 form.
You can view the request body the requests library is sending by:
response.request.body
It returns
'name=John&lastname=Doe&email=jd%40gmail.com&is_staff=True'
In this case the boolean you are sending is turned into "True" or "False". The problem could be that the webserver is expecting a "true" or "false" instead but it depends on the server.
Try:
data = {
'name': 'John',
'lastname': "Doe",
'email': "jd#gmail.com",
'is_staff' : "true"
}
Or the dynamic:
is_staff = True
data = {
'name': "John",
'lastname': "Doe",
'email': "jd#gmail.com",
'is_staff' : str(is_staff).lower()
}

Related

Unable to access JSON data from Javascript

I am passing the following from my Django back-end to my front-end in order to dynamically build a form :
{
"access_key": "93ec6137de00eacee6f8",
"profile_id": "7851E15D64",
"transaction_uuid": "c878c7e6db5657526",
}
Within the browser console, if I pass :
MyJSON = {
"access_key": "93ec6137de00eacee6f8",
"profile_id": "7851E15D64",
"transaction_uuid": "c878c7e6db5657526",
}
Then I can access each value properly, for example, MyJSON.access_key returns 93ec6137de00eacee6f8 perfectly within the console.
However, from my Javascript, I am unable to access any of those values as i get an "undefined".
var obj = JSON.parse(MyJSON)
console.log(obj) // returns the whole JSON String
console.log(typeof(obj)) // returns 'string'
alert(obj[0]) // returns "{", the very first character of the 'string'
alert(obj.access_key) // returns "undefined".
- How can access each Key and Value from MyJSON from my javascript? (not JQuery)
Note that I have reviewed many similar article but I must be missing the obvious ...
Hope you can assist !
Thanks in advance.
EDIT :
I have a list of Fields and a list of Values which i then merge into the below (pass the JSON Validator on https://jsonlint.com/):
{'access_key': '93ec6137d70aada23400eacee6f8', 'profile_id': '7851E53E-96BB-4D4-BD5-0FE61CC15D64', 'transaction_uuid': '00939a90-db7b-41cb-af45-669ec5cc69e8', 'signed_field_names': 'bill_to_forename,bill_to_surname,bill_to_email,bill_to_phone,bill_to_address_line1,bill_to_address_city,bill_to_address_postal_code,bill_to_address_country,transaction_type,reference_number,payment_method,amount,currency,locale,card_type,card_number,card_expiry_date', 'unsigned_field_names': 'card_type,card_number,card_expiry_date', 'signed_date_time': '2021-05-23T16:20:17Z', 'bill_to_forename': 'John', 'bill_to_surname': 'Doe', 'bill_to_email': 'null#cfgfg.com', 'bill_to_phone': '07922889582', 'bill_to_address_line1': '123 Random Street', 'bill_to_address_city': 'London', 'bill_to_address_postal_code': 'RG1T3X', 'bill_to_address_country': 'GB', 'transaction_type': 'sale', 'reference_number': 'o6yejf', 'payment_method': 'card', 'amount': '100', 'currency': 'USD', 'locale': 'en', 'card_type': '001', 'card_number': '4456530000001096', 'card_expiry_date': '12-2026', 'signature': 'Un5gNYB5qZaRazzCDWqrdZuNkTRARIcfAt9aF2a1wbY='}
Back-end Code
FieldList = ['access_key', 'profile_id', 'transaction_uuid', 'signed_field_names', 'unsigned_field_names', 'signed_date_time', 'bill_to_forename', 'bill_to_surname', 'bill_to_email', 'bill_to_phone', 'bill_to_address_line1', 'bill_to_address_city', 'bill_to_address_postal_code', 'bill_to_address_country', 'transaction_type', 'reference_number', 'payment_method', 'amount', 'currency', 'locale', 'card_type', 'card_number', 'card_expiry_date', 'signature']
ValueList = ['93ec6137d0aada23400eacee6f8', '7851E53E-96BB-4DF4-BD55-0FE61CC15D64', 'c4fe96b0-063f-4b94-a6a5-2137bb796bd9', 'bill_to_forename,bill_to_surname,bill_to_email,bill_to_phone,bill_to_address_line1,bill_to_address_city,bill_to_address_postal_code,bill_to_address_country,transaction_type,reference_number,payment_method,amount,currency,locale,card_type,card_number,card_expiry_date', 'card_type,card_number,card_expiry_date', '2021-05-23T16:27:24Z', 'John', 'Doe', 'null#cyrce.com', '07922889582', '123 Random Street', 'London', 'RG1T3X', 'GB', 'sale', 'xl42fn', 'card', '100', 'USD', 'en', '001', '4456530000001096', '12-2026', 'vvb73h0GUpzUrvoG9VDaMc3vQRV5GsL4QTATc7IrrPA=']
NewFormat = dict(zip(FieldList, ValueList))
MyJSON = json.dumps(NewFormat, indent=4)
return JsonResponse(MyJSON, safe=False)
Apologies for the large amount of data.
I am somehow forced to use "safe=False" in my Python back-end otherwise I end up with :
Traceback (most recent call last):
File "/home/pi/.local/lib/python3.7/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/home/pi/.local/lib/python3.7/site-packages/django/core/handlers/base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/pi/Documents/Droplet/Droplet/Harness/sasop2.py", line 543, in signsasop
return JsonResponse(FinalJSONObject)
File "/home/pi/.local/lib/python3.7/site-packages/django/http/response.py", line 561, in __init__
'In order to allow non-dict objects to be serialized set the '
TypeError: In order to allow non-dict objects to be serialized set the safe parameter to False.
Since I am passing safe=False, is that why my front-end does not get the MyJSON as... JSON?
Would this be the root cause of the issue?
Front-End Sample :
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
// Print received data from server
console.log('%c Processed Data \n',
'background: #000000; color: #FFFFFF; font-size: 30px'
,xhr.response);
// Dynamically create the ReconstructedForm
RawProcessedData = xhr.response
console.log(RawProcessedData)
// Convert to JSON
var obj = JSON.parse(RawProcessedData)
console.log(obj)
console.log(typeof(obj))
alert(obj[0])
alert(obj.access_key)
Thanks a lot for your quick input !
As per deceze's answer, I was essentially double parsing both in the back and front end for no reasons.
Removing the json.dumps from the backend allows the JSON object to be passed and managed in the front end without issue.
I have the same issue when i started developing on Django. If you need to pass dictionarys from django to javascripts, the best thing to do is just using django rest framework. It serialize ( in other words, it transform any data into a dictionary/json ) any given data from a model.
But if you want to make this without Django Rest, you should use fetch on javascript. This fetch ( also called as a "Promise") communicate with the backend ( in this case, Django ) and it GET or POST data from the frontend. I will give you an example.
Supose you have this on views.py:
from django.http.response import JsonResponse
def getJSON(request):
MyJSON = {
"access_key": "93ec6137de00eacee6f8",
"profile_id": "7851E15D64",
"transaction_uuid": "c878c7e6db5657526",
}
return JsonResponse(MyJSON)
And the you can link that to the urls.py like this:
urlpatterns = [
path('get-json', views.getJSON, name="get-json")
]
Then you can GET that JSON by doing this on your javascript:
function getDataJson(){
let url = 'get-json'
fetch(url,{
headers: {
"Content-type": "application/json",
},
})
.then(response => response.json())
.then(data=> console.log(data))
}
This will console log your data.

how to get_argument from nested dictionary and array in tornado

JavaScript client sending request like this:
$.ajax({
url: 'http://localhost:7973/test',
type: 'GET',
data: {'host': 'mike', 'guests': {'name': ['car', 'ball'], 'age': [6, 10, 7]}},
success: function(result){alert(result)},
error: function(error){alert(error)}
});
Python server handling request using tornado:
import tornado.ioloop
import tornado.web
class TestHandler(tornado.web.RequestHandler):
def get(self):
host = self.get_argument('host')
print(host)
guests = self.get_argument('guests')
print(guests)
def make_app():
return tornado.web.Application([
(r'/test', TestHandler)
])
if __name__ == "__main__":
app = make_app()
port = 7973
app.listen(port)
print('-' * 100)
print('server started, listening to ', port, '...\n')
tornado.ioloop.IOLoop.current().start()
The outputs on the server side is as below. Apparently, the 'host' argument is successfully got, but I have no clue how to get a argument whose value is a complex object itself (say an array or a dictionary). Please explain to me the mechanism of these casts and dumps between data structures and their string representation? I read the tornado document, but I'm not able to find the answer.
mike
WARNING:tornado.general:400 GET
/test?host=mike&guests%5Bname%5D%5B%5D=car&guests%5Bname%5D%5B%5D=ball&guests%5Bage%5D%5B%5D=6&guests%5Bage%5D%5B%5D=10&guests%5Bage%5D%5B%5D=7
(::1): Missing argument guests
WARNING:tornado.access:400 GET
/test?host=mike&guests%5Bname%5D%5B%5D=car&guests%5Bname%5D%5B%5D=ball&guests%5Bage%5D%5B%5D=6&guests%5Bage%5D%5B%5D=10&guests%5Bage%5D%5B%5D=7
(::1) 1.99ms
You can convert your json object to a json string.
change
data: {'host': 'mike', 'guests': {'name': ['car', 'ball'], 'age': [6, 10, 7]}},
to
data: JASON.stringify({'host': 'mike',
'guests': {'name': ['car', 'ball'],
'age': [6, 10, 7]}}),
and then on the server side you can do:
guests_string = self.get_argument('guests')
guests = json.loads(guests_string)
guests should be a dictionary that you can do whatever with in Python.

Dynamic http post parameter name in AngularJS

I'm using an API for updating profile, by adding nickname, email, phone or password in request parameters each of them will be updated in database.
I want to pass one of these each time depending on user's choice for example when I want to update Nick name:
{
"nickname": "alifa",
"device_id": "chrome",
"device_model": "browser",
"device_os": "angularJS"
}
or for updating email:
{
"email": "info#example.com",
"device_id": "chrome",
"device_model": "browser",
"device_os": "angularJS"
}
I want to do this by passing property name and property value to a function and it will make an object and send http post request:
this.updateDetails = function(dataName, dataValue){
Loader.global.show();
var data = $.param({
device_id: app.device_id,
device_os: app.device_os,
device_model: app.device_model
});
data[dataName] = dataValue;
console.log(data);
return $http.post(app.baseUrl + 'profile/' , data).success(function(){
Loader.global.hide();
}).error(function(){
Loader.global.hide();
})
}
but what it sends to server is just:
Is there any possible way to do this?
You need to modify the object you pass to param. Adding a property to the string you get out of param is pointless.
var data = {
device_id: app.device_id,
device_os: app.device_os,
device_model: app.device_model
};
data[dataName] = dataValue;
var encoded_data = $.param(data);

Sending "CC" and "BCC" in substitution data when calling Node SparkPost API

I have templates created in SparkPost dashboard. But the problem I face is that I am not able to send "CC" or "BCC" by making the api calls. The code snippet below will help you understand what I am trying to do.
var SPARKPOST_KEY = "KEY"
var sparkpost = require('sparkpost');
var sparkclient = new sparkpost(SPARKPOST_KEY);
var req_opts = {
transmissionBody : {
content: {
template_id: 'order-confirmation',
from: 'support#domain.in',
subject: 'Order confirmation',
headers: {
"CC": "<anon2#gmail.com>"
}
},
substitution_data: {
"CC": "anon2#gmail.com",
"customer": "Aravind",
"order": 123532
},
recipients: [
{address: {email:'anon1#domain1.in'}},
{address: {email: 'anon2#gmail.com'}}
],
"return_path": "support#domain.in",
}
};
sparkclient.transmissions.send(req_opts, function(err, res){
if(err){
console.log("ERROR");
console.log(err)
}else {
console.log(res.body);
console.log("Mail has been successfully sent");
}
});
As mentioned in the reply on your github issue, you must use either inline content or a template. So as the documentation says, use just template_id in your content.
What needs to happen for this to work is that the headers in the template include a CC header, as described here. Currently there is no way to set the headers of a template in the UI -- it must be done using the API.
To do this execute a PUT against the templates endpoint, in your case https://api.sparkpost.com/api/v1/templates/order-confirmation, with a JSON payload containing the following:
{
"content": {
<other content parts>
"headers": {
"CC": "{{CC}}"
}
}
}
Note that you will also need to use the header_to parameter for your CC recipient to prevent their address showing up in the To: header. In your example this means replacing:
{address: {email: 'anon2#gmail.com'}}
with this:
{address: {email: 'anon2#gmail.com', header_to: 'anon1#domain1.in'}}
You also do not need the return_path parameter.
Hope this helps!

Creating an envelope from a template returning "UNSPECIFIED_ERROR"

When I try to create an envelope from a template I get a response of:
{ errorCode: 'UNSPECIFIED_ERROR',
message: 'Non-static method requires a target.' }
Here's what I'm doing so far:
First I login, which returns
{ loginAccounts:
[ { name: '*****',
accountId: '*****',
baseUrl: 'https://demo.docusign.net/restapi/v2/accounts/******',
isDefault: 'true',
userName: '***** ********',
userId: '*******-*****-*****-*****-*********',
email: '********#*******.com',
siteDescription: '' } ] }
So then I take the baseUrl out of that response and I attempt to create the envelope. I'm using the hapi framework and async.waterfall of the async library, so for anyone unfamiliar with either of these my use of the async library uses the next callback to call the next function which in this case would be to get the url for the iframe, and with our usage of the hapi framework AppServer.Wreck is roughy equivalent to request:
function prepareEnvelope(baseUrl, next) {
var createEntitlementTemplateId = "99C44F50-2C97-4074-896B-2454969CAEF7";
var getEnvelopeUrl = baseUrl + "/envelopes";
var options = {
headers: {
"X-DocuSign-Authentication": JSON.stringify(authHeader),
"Content-Type": "application/json",
"Accept": "application/json",
"Content-Disposition": "form-data"
},
body : JSON.stringify({
status: "sent",
emailSubject: "Test email subject",
emailBlurb: "My email blurb",
templateId: createEntitlementTemplateId,
templateRoles: [
{
email: "anemailaddress#gmail.com",
name: "Recipient Name",
roleName: "Signer1",
clientUserId: "1099", // TODO: replace with the user's id
tabs : {
textTabs : [
{
tabLabel : "acct_nmbr",
value : "123456"
},
{
tabLabel : "hm_phn_nmbr",
value : "8005882300"
},
{
tabLabel : "nm",
value : "Mr Foo Bar"
}
]
}
}
]
})
};
console.log("--------> options: ", options); // REMOVE THIS ====
AppServer.Wreck.post(getEnvelopeUrl, options, function(err, res, body) {
console.log("Request Envelope Result: \r\n", JSON.parse(body));
next(null, body, baseUrl);
});
}
And what I get back is:
{ errorCode: 'UNSPECIFIED_ERROR',
message: 'Non-static method requires a target.' }
From a little googling it look like 'Non-static method requires a target.' is a C# error and doesn't really give me much indication of what part of my configuration object is wrong.
I've tried a simpler version of this call stripping out all of the tabs and clientUserId and I get the same response.
I created my template on the Docusign website and I haven't ruled out that something is set up incorrectly there. I created a template, confirmed that Docusign noticed the named form fields, and created a 'placeholder' templateRole.
Here's the templateRole placeholder:
Here's one of the named fields that I want to populate and corresponding data label:
As a side note, I was able to get the basic vanilla example working without named fields nor using a template using the docusign node package just fine but I didn't see any way to use tabs with named form fields with the library and decided that I'd rather have more fine-grained control over what I'm doing anyway and so I opted for just hitting the APIs.
Surprisingly when I search SO for the errorCode and message I'm getting I could only find one post without a resolution :/
Of course any help will be greatly appreciated. Please don't hesitate to let me know if you need any additional information.
Once I received feedback from Docusign that my api call had an empty body it didn't take but a couple minutes for me to realize that the issue was my options object containing a body property rather than a payload property, as is done in the hapi framework.

Categories

Resources