how to access GET query string multidimensional arrays in bottle python - python

I know how to get individual values from keys such as:
some_val = request.query.some_key
But how do you access values when you have a url like this.
Sample url :
http://blahblah.com/what?draw=1&columns%5B0%5D%5Bdata%5D=source_url&columns%5B0%5D%5Bname%5D=&columns%5B0%5D%5Bsearchable%5D=true&columns%5B0%5D%5Borderable%5D=true&columns%5B0%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B0%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B1%5D%5Bdata%5D=total_size&columns%5B1%5D%5Bname%5D=&columns%5B1%5D%5Bsearchable%5D=true&columns%5B1%5D%5Borderable%5D=true&columns%5B1%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B1%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B2%5D%5Bdata%5D=total_time&columns%5B2%5D%5Bname%5D=&columns%5B2%5D%5Bsearchable%5D=true&columns%5B2%5D%5Borderable%5D=true&columns%5B2%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B2%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B3%5D%5Bdata%5D=tag_name&columns%5B3%5D%5Bname%5D=&columns%5B3%5D%5Bsearchable%5D=true&columns%5B3%5D%5Borderable%5D=true&columns%5B3%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B3%5D%5Bsearch%5D%5Bregex%5D=false&order%5B0%5D%5Bcolumn%5D=0&order%5B0%5D%5Bdir%5D=asc&start=0&length=10&search%5Bvalue%5D=&search%5Bregex%5D=false&_=1476782117541
What the params look like decoded:
_
1476782117541
columns[0][data]
source_url
columns[0][name]
columns[0][orderable]
true
columns[0][search][regex]
false
columns[0][search][value]
columns[0][searchable]
true
columns[1][data]
total_size
columns[1][name]
columns[1][orderable]
true
columns[1][search][regex]
false
columns[1][search][value]
columns[1][searchable]
true
columns[2][data]
total_time
columns[2][name]
columns[2][orderable]
true
columns[2][search][regex]
false
columns[2][search][value]
columns[2][searchable]
true
columns[3][data]
tag_name
columns[3][name]
columns[3][orderable]
true
columns[3][search][regex]
false
columns[3][search][value]
columns[3][searchable]
true
draw
1
length
10
order[0][column]
0
order[0][dir]
asc
search[regex]
false
search[value]
start
0
I have tried
request.query.getall('order')
or
request.query.decode()
I am trying to parse the params that are sent automatically by datatables so i can modify my query accordingly.

Since this question pertains to using https://datatables.net/ with a bottle python backend. What i ended up doing is formatting the args on the client side like so. Maybe you'll find it useful.
$('#performance-table').DataTable( {
"ajax": {
"url" : "http://someapi.com/dt_set",
"type": 'GET',
"beforeSend": function (request) {
request.setRequestHeader("Authorization", "Bearer " + token);
},
data: function ( args ) {
margs = {}
margs.page_nr = args.draw;
margs.how_many = args.length;
margs.sort_column = args.columns[args.order[0].column].data;
margs.sort_direction = args.order[0].dir;
//return args;
return margs;
}
},
"processing": true,
"serverSide": true,
"columns": [
{ "data": "source_url" },
{ "data": "total_size" },
{ "data": "total_time" },
{ "data": "tag_name" }
]
});

Related

How to count value occurrences in json response using python?

I have a json response that looks like below and I would like to count how many times corrId has been mentioned.
{
"result":
{
"corrList":[
{
"corrId":123456,
"title":"sample1",
},
{
"corrId":45678,
"title":"sample2",
},
{
"corrId":987654,
"title":"sample3",
}
],
"find":true
}
}
For the above, I would expect result to be 3
I have tried something like above, but it throws an error:
r = requests.get(url = HOSTNAME + endpoint, headers = headers, verify=False)
data = json.loads(r.text)
corrList = len(data['corrList'][0]['corrId'])
print (corrList)
My error:
TypeError: object of type 'int' has no len()
Would someone be able to help? thanks in advance!
You need to actually count the number of dicts that have that key:
data = {
"result":
{
"corrList":[
{
"corrId":123456,
"title":"sample1",
},
{
"corrId":45678,
"title":"sample2",
},
{
"corrId":987654,
"title":"sample3",
}
],
"find":True
}
}
corrList = [item for item in data['result']['corrList'] if 'corrId' in item]
print(len(corrList))
Output 3

Is there a way to get the particular Values from JSON Array using robot or Python code?

JSON OUTPUT:
${response}= [
{
"Name":"7122Project",
"checkBy":[
{
"keyId":"NA",
"target":"1232"
}
],
"Enabled":false,
"aceess":"123"
},
{
"Name":"7122Project",
"checkBy":[
{
"keyId":"_GU6S3",
"target":"123"
}
],
"aceess":"11222",
"Enabled":false
},
{
"Name":"7122Project",
"checkBy":[
{
"keyId":"-1lLUy",
"target":"e123"
}
],
"aceess":"123"
}
]
Need to get the keyId values from json without using hardcoded index using robot?
I did
${ID}= set variable ${response[0]['checkBy'][0]['keyId']}
But I need to check the length get all keyID values and store the values that dose not contain NA
How can I do check length and use for loop using robot framework?
I suppose you can have more elements in checkBy arrays, like so:
response = [
{
"Name":"7122Project",
"checkBy": [
{
"keyId": "NA",
"target": "1232"
}
],
"Enabled": False,
"aceess": "123"
},
{
"Name": "7122Project",
"checkBy": [
{
"keyId": "_GUO6g6S3",
"target": "123"
}
],
"aceess": "11222",
"Enabled": False
},
{
"Name": "7122Project",
"checkBy": [
{
"keyId": "-1lLlZOUy",
"target": "e123"
},
{
"keyId": "test",
"target": "e123"
}
],
"aceess": "123"
}
]
then you can key all keyIds in Python with this code:
def get_key_ids(response):
checkbys = [x["checkBy"] for x in response]
key_ids = []
for check_by in checkbys:
for key_id in check_by:
key_ids.append(key_id["keyId"])
return key_ids
for the example above, it will return: ['NA', '_GUO6g6S3', '-1lLlZOUy', 'test_NA'].
You want to get both ids with NA and without NA, so perhaps you can change the function a bit:
def get_key_ids(response, predicate):
checkbys = [x["checkBy"] for x in response]
key_ids = []
for check_by in checkbys:
for key_id in check_by:
if predicate(key_id["keyId"]):
key_ids.append(key_id["keyId"])
return key_ids
and use it like so:
get_key_ids(response, lambda id: id == "NA") # ['NA']
get_key_ids(response, lambda id: id != "NA") # ['_GUO6g6S3', '-1lLlZOUy', 'test_NA']
get_key_ids(response, lambda id: "NA" in id) # ['NA', 'test_NA']
get_key_ids(response, lambda id: "NA" not in id) # ['_GUO6g6S3', '-1lLlZOUy']
Now it's just a matter of creating a library and importing it into RF. You can get inspiration in the official documentation.
But I need to check the length get all keyID values and store the values that dose not contain NA
I don't completely understand what you are up to. Do you mean length of keyId strings, like "NA" and its length of 2, or the number of keyIds in the response?
How can I do check length and use for loop using robot framework?
You can use keyword Should Be Equal * from BuiltIn library. Some examples of for loops could be found in the user guide here.
Now you should have all the parts you need to accomplish your task, you can try to put it all together.

Cant Access Data in List of Dictionaries

I'm trying to access some data within nested ordered dictionaries. This dictionary was created by using the XMLTODICT module. Obviously I would like to create my own dictionaries but this one is out of my control.
I've tried to access them numerous ways.
Example:
Using a for loop:
I can access the first level using v["name"] which gives me Child_Policy and Parent Policy
When I do v["class"]["name"] I would expect to get "Test1" but that's not the case.
I've also tried v[("class", )] variations as well with no luck.
Any input would be much appreciated
The data below is retrieved from a device via XML and converted to dictionary with XMLTODICT.
[
{
"#xmlns": "http://cisco.com/ns/yang/Cisco-IOS-XE-policy",
"name": "Child_Policy",
"class": [
{
"name": "Test1",
"action-list": {
"action-type": "bandwidth",
"bandwidth": {
"percent": "30"
}
}
},
{
"name": "Test2",
"action-list": {
"action-type": "bandwidth",
"bandwidth": {
"percent": "30"
}
}
}
]
},
{
"#xmlns": "http://cisco.com/ns/yang/Cisco-IOS-XE-policy",
"name": "Parent_Policy",
"class": {
"name": "class-default",
"action-list": [
{
"action-type": "shape",
"shape": {
"average": {
"bit-rate": "10000000"
}
}
},
{
"action-type": "service-policy",
"service-policy": "Child_Policy"
}
]
}
}
]
My expectations result is to retrieve values from the nested dictionary and produce and output similar to this:
Queue_1: Test1
Action_1: bandwidth
Allocation_1: 40
Queue_2: Test2
Action_2: bandwidth
Allocation_2: 10
I have now issue formatting the output, just getting the values is the issue.
#
I had some time tonight so I changed the code be be dynamic:
int = 0
int_2 = 0
for v in policy_dict.values():
print("\n")
print("{:15} {:<35}".format("Policy: ", v[0]["name"]))
print("_______")
for i in v:
int_2 = int_2 + 1
try:
print("\n")
print("{:15} {:<35}".format("Queue_%s: " % int_2, v[0]["class"][int]["name"]))
print("{:15} {:<35}".format("Action_%s: " % int_2, v[0]["class"][int]["action-list"]["action-type"]))
print("{:15} {:<35}".format("Allocation_%s: " % int_2, v[0]["class"][int]["action-list"]["bandwidth"]["percent"]))
int = int + 1
except KeyError:
break
pass
According to the sample you posted you can try to retrieve values like:
v[0]["class"][0]["name"]
This outputs:
Test1

Add a Protected Range to an existing NamedRange

I have an existing worksheet with an existing NamedRange for it and I would like to call the batch_update method of the API to protect that range from being edited by anyone other than the user that makes the batch_update call.
I have seen an example on how to add protected ranges via a new range definition, but not from an existing NamedRange.
I know I need to send the addProtectedRangeResponse request. Can I define the request body with a Sheetname!NamedRange notation?
this_range = worksheet_name + "!" + nrange
batch_update_spreadsheet_request_body = {
'requests': [
{
"addProtectedRange": {
"protectedRange": {
"range": {
"name": this_range,
},
"description": "Protecting xyz",
"warningOnly": False
}
}
}
],
}
EDIT: Given #Tanaike feedback, I adapted the call to something like:
body = {
"requests": [
{
"addProtectedRange": {
"protectedRange": {
"namedRangeId": namedRangeId,
"description": "Protecting via gsheets_manager",
"warningOnly": False,
"requestingUserCanEdit": False
}
}
}
]
}
res2 = service.spreadsheets().batchUpdate(spreadsheetId=ssId, body=body).execute()
print(res2)
But although it lists the new protections, it still lists 5 different users (all of them) as editors. If I try to manually edit the protection added by my gsheets_manager script, it complains that the range is invalid:
Interestingly, it seems to ignore the requestUserCanEdit flag according to the returning message:
{u'spreadsheetId': u'NNNNNNNNNNNNNNNNNNNNNNNNNNNN', u'replies': [{u'addProtectedRange': {u'protectedRange': {u'requestingUserCanEdit': True, u'description': u'Protecting via gsheets_manager', u'namedRangeId': u'1793914032', u'editors': {}, u'protectedRangeId': 2012740267, u'range': {u'endColumnIndex': 1, u'sheetId': 1196959832, u'startColumnIndex': 0}}}}]}
Any ideas?
How about using namedRangeId for your situation? The flow of the sample script is as follows.
Retrieve namedRangeId using spreadsheets().get of Sheets API.
Set a protected range using namedRangeId using spreadsheets().batchUpdate of Sheets API.
Sample script:
nrange = "### name ###"
ssId = "### spreadsheetId ###"
res1 = service.spreadsheets().get(spreadsheetId=ssId, fields="namedRanges").execute()
namedRangeId = ""
for e in res1['namedRanges']:
if e['name'] == nrange:
namedRangeId = e['namedRangeId']
break
body = {
"requests": [
{
"addProtectedRange": {
"protectedRange": {
"namedRangeId": namedRangeId,
"description": "Protecting xyz",
"warningOnly": False
}
}
}
]
}
res2 = service.spreadsheets().batchUpdate(spreadsheetId=ssId, body=body).execute()
print(res2)
Note:
This script supposes that Sheets API can be used for your environment.
This is a simple sample script. So please modify it to your situation.
References:
ProtectedRange
Named and Protected Ranges
If this was not what you want, I'm sorry.
Edit:
In my above answer, I modified your script using your settings. If you want to protect the named range, please modify body as follows.
Modified body
body = {
"requests": [
{
"addProtectedRange": {
"protectedRange": {
"namedRangeId": namedRangeId,
"description": "Protecting xyz",
"warningOnly": False,
"editors": {"users": ["### your email address ###"]}, # Added
}
}
}
]
}
By this, the named range can be modified by only you. I'm using such settings and I confirm that it works in my environment. But if in your situation, this didn't work, I'm sorry.

Check if key/value is in JSON

With this code
import sense
import json
sense.api_key = '...'
node = sense.Node.retrieve('........')
feed = node.feeds.retrieve('presence')
events = feed.events.list(limit=1)
result = json.dumps(events,indent=1)
print result
I get a JSON-Feed like this:
{
"links": {...},
"objects": [
{
"profile": "GenStandard",
"feedUid": ".....",
"gatewayNodeUid": ".....",
"dateServer": "2015-02-28T09:57:22.337034",
"geometry": null,
"data": {
"body": "Present",
"code": 200
},
"signal": "-62",
"dateEvent": "2015-02-28T09:57:22.000000",
"type": "presence",
"payload": "2",
"nodeUid": "....."
}
],
"totalObjects": 875,
"object": "list"
}
How can I check if 'body' is 'present' (or 'code' is '200')? My script should return TRUE or FALSE
UPDATE
If I add this code as proposed in the answers it works fine:
d=json.loads(result)
def checkJson(jsonContents):
bodyFlag = True if "body" in jsonContents["objects"][0]["data"] and jsonContents["objects"][0]["data"]["body"] == "Present" else False
return bodyFlag
print checkJson(d)
You should also maybe check if the body key is actually there.
def checkJson(jsonContents):
bodyFlag = True if "body" in jsonContents["objects"][0]["data"] and jsonContents["objects"][0]["data"]["body"] == "Present" else False
codeFlag = True if "code" in jsonContents["objects"][0]["data"] and jsonContents["objects"][0]["data"]["code"] == 200 else False
return bodyFlag or codeFlag
print checkJson(result)
d = json.loads(results)
objs = d["objects"][0]
# see if any code is either == 200 or "body" is a key in the subdict
return any(x for x in (objs["data"]["code"] == 200,"body" in objs["data"]))

Categories

Resources