How to fix this error in my appsync while creating an array of data - amazon-web-services

I am creating an array of date and in my resolver it only return one output of date and count audited
I search throughout the google to find some answer and I found a code how to make an array of list but the problem is it didn't return well
https://imgur.com/a/1eDknYN
this is a result and the code I use it attached in the picture
#set ($tu = 0) #set ($pc = 0) #set ($fc = 0) #set ($da = [])#set ($cda = []) #foreach($item in $ctx.result.items)
#set($tu = $item.total_audits + $tu)
#set($pc = $item.passed_compliance + $pc)
#set($fc = $item.failed_compliance + $fc)
#set($date = $item.sort)
#set($count = $item.total_audits)
$util.qr($da.add("$date"))
$util.qr($cda.add("$count"))
#end
$util.toJson({"total_audits":$tu, "passed_compliance":$pc,
"failed_compliance":$fc, "daily_audit": [{"date": $da, "count": $cda}]})
here is the error
"errors": [
{
"path": [
"getAuditSummary",
"daily_audit",
0,
"date"
],
"locations": null,
"message": "Can't serialize value (/getAuditSummary/daily_audit[0]/date) : Unable to serialize `[2018-12-26, 2018-12-27, 2018-12-28]` as a valid date."
},
{
"path": [
"getAuditSummary",
"daily_audit",
0,
"count"
],
"locations": null,
"message": "Can't serialize value (/getAuditSummary/daily_audit[0]/count) : Expected type 'Int' but was 'ArrayList'."
what i want to make is it would return something like this
"daily_audit": [
{
"date": 2018-12-26,
"count": 1
}
{
"date": 2018-12-27,
"count": 4
}
{
"date": 2018-12-28,
"count": 2
}
]

This is happening because $da and $cda are arrays. So it's probably returning:
"daily_audit": [
{
"date": [2018-12-26,2018-12-27,2018-12-28],
"count": [1,4,2]
}
]
So, in your response mapping template, you can try something like:
#set ($tu = 0)
#set ($pc = 0)
#set ($fc = 0)
#set ($da = [])
#foreach($item in $ctx.result.items)
#set($tu = $item.total_audits + $tu)
#set($pc = $item.passed_compliance + $pc)
#set($fc = $item.failed_compliance + $fc)
#set($date = $item.sort)
#set($count = $item.total_audits)
$util.qr($da.add({"date":$date, "count":$count}))
#end
$util.toJson({"total_audits":$tu, "passed_compliance":$pc, "failed_compliance":$fc, "daily_audit": $da})

Related

How can I get distinct values for the area.names using graphene?

my resolver in schema.py looks like this
def resolve_areas(self, info, **kwargs):
result = []
dupfree = []
user = info.context.user
areas = BoxModel.objects.filter(client=user, active=True).values_list('area_string', flat=True)
In GraphiQL I am using this query:
{
areas {
edges {
node {
id
name
}
}
}
}
And get Output that starts like this:
{
"data": {
"areas": {
"edges": [
{
"node": {
"id": "QXJlYTpkZWZ",
"name": "default"
}
},
{
"node": {
"id": "QXJlYTptZXN",
"name": "messe"
}
},
{
"node": {
"id": "QXJlYTptZXN",
"name": "messe"
}
},
But i want distinct values on the name variable
(Using a MySQL Database so distinct does not work)
SOLVED:
distinct was not working. so i just wrote a short loop which tracked onlye the string names duplicates in a list and only appended the whole "area" object if it's name has not been added to the duplicates list yet
result = []
dupl_counter = []
for area in areas:
if area not in dupl_counter:
dupl_counter.append(area)
result.append(Area(name=area))
print(area)

Odd ColdFusion cfscript syntax issue

I'm having a very odd syntax error in my cfscript.
stFields = {
"EligibilityQuery": {
"Patient": {
"FirstName": arguments.data.lname,
"MiddleName": "",
"LastName": arguments.data.fname,
"DateOfBirth": dateformat(arguments.data.dob,'yyyy-mm-dd'),
"Gender": arguments.data.gender,
"SSN": arguments.data.SSN,
"Address": {
"FirstLine": "",
"SecondLine": "",
"ZipCode": arguments.data.ZipCode
}
},
"NPI": "1111111"
}
};
// call API
var authorization = "Basic: " & ToBase64('username:password');
cfhttp(method="POST", url="https://mysite/api/myAPI/", result="apiResult"){
cfhttpparam(name="Authorization", type="header", value="#authorization#");
cfhttpparam(name="Content-Type", type="header", value="application/json");
cfhttpparam(type="body", value="#serializeJSON(stFields)#");
}
apiResult = deserializeJSON(apiResult.fileContent);
It's returning error on cfhttp (A script statement must end with ";".)
Error - The CFML compiler was processing:
cfhttp(method="POST", url="https://mysite/api/myAPI/", result="apiResult")
Where am I missing the ";"?
Expects a ; after cfhttp(method="POST", url="https://mysite/api/myAPI/", result="apiResult").
Are you on CF9 or CF10? Try this:
// call API
var authorization = "Basic: " & ToBase64('username:password');
httpService = new http(method = "POST", charset = "utf-8", url = "https://mysite/api/myAPI/");
httpService.addParam(name = "Authorization", type = "header", value = "#authorization#");
httpService.addParam(name = "Content-Type", type = "header", value = "application/json");
httpService.addParam(type = "body", value = "#serializeJSON(stFields)#");
apiResult = httpService.send().getPrefix();
apiResult = deserializeJSON(apiResult.fileContent);

Determine velocity template request body property type?

I have an API Gateway that uses velocity templates as a thin wrapper to allow users to do CRUD operations on a DynamoDB table.
I'm trying to write the update operation as dynamically as possible, but where I'm stuck is with determining type from the request body's properties from within the velocity template. This is what I'm working with:
#set($body = $input.path('$'))
#set($updateExpression = "set")
#set($expressionAttributeNames = "")
#set($expressionAttributeValues = "")
#foreach($attrName in $body.keySet())
#set($updateExpression = "${updateExpression} #$attrName = :${attrName},")
#set($expressionAttributeNames = "${expressionAttributeNames}""#${attrName}"":""${attrName}""")
#set($attrValue = $input.json("$.${attrName}"))
#if($attrValue.matches("^-?\\d+$"))
#set($attrValue = """:${attrName}"": { ""N"": ${attrValue}, ")
#else
#set($attrValue = """:${attrName}"": { ""S"": """ + $util.escapeJavaScript($attrValue) + """ },")
#end
#set($expressionAttributeValues = "${expressionAttributeValues} ${attrValue}")
#if($foreach.hasNext)
#set($expressionAttributeNames = "${expressionAttributeNames}, ")
#end
#end
{
"TableName": "TABLE",
"Key": { "id": { "S": "$input.params('id')" } },
"UpdateExpression": "${updateExpression} updatedOn = :updatedOn",
"ExpressionAttributeNames": {$expressionAttributeNames},
"ExpressionAttributeValues": {
$expressionAttributeValues
":updatedOn": { "N": "$context.requestTimeEpoch" }
}
}
Edit: This would be a sample request body:
https://api/v1/endpoint/123
{
"location": {
"lat": 42,
"lon": -71
},
"rating": 4
}
This is the current transformation I get:
{
"TableName": "users",
"Key": { "gcn": { "S": "123" } },
"UpdateExpression": "set #number = :number, #location = :location, updatedOn = :updatedOn",
"ExpressionAttributeNames": {"#number":"number", "#location":"location"},
"ExpressionAttributeValues": {
":number": { "S": "1" }, ":location": { "S": "{\"lat\":26.89199858375187,\"lon\":75.77141155196833}" },
":updatedOn": { "N": "" }
}
}
I currently just have a test for checking if a value is a number...and it isn't working.
After doing some more digging I reached what I set out for. I have a dynamic Velocity Template mapping for AWS API Gateway for the purpose of updating DynamoDB items.
So far it supports strings, numbers, booleans, and string-escaped objects, as that's how my project stores them (they are not query-able). ExpressionAttributeNames exists in case you use a reserved keyword for an attribute name...like I did for 'location'.
If anyone has any improvements/enhancements please let me know, it's a beast of a script.
#set($body = $input.path('$'))
#set($updateExpression = "set")
#set($expressionAttributeNames = "")
#set($expressionAttributeValues = "")
#foreach($attrName in $body.keySet())
#set($updateExpression = "${updateExpression} #$attrName = :${attrName},")
#set($expressionAttributeNames = "${expressionAttributeNames}""#${attrName}"":""${attrName}""")
#set($attrValue = $input.json("$.${attrName}"))
#if($attrValue.toString().matches("[+-]?\d+"))
#set($attrValue = """:${attrName}"": { ""N"": ""${attrValue}"" }, ")
#elseif($attrValue.toString() == "true" || $attrValue.toString() == "false")
#set($attrValue = """:${attrName}"": { ""BOOL"": ${attrValue} }, ")
#elseif(($attrValue.toString().startsWith("{") && $attrValue.toString().endsWith("}")) ||
($attrValue.toString().startsWith("[") && $attrValue.toString().endsWith("]")) )
#set($attrValue = """:${attrName}"": { ""S"": """ + $util.escapeJavaScript($attrValue) + """ },")
#else
#set($attrValue = """:${attrName}"": { ""S"": " + $attrValue + " },")
#end
#set($expressionAttributeValues = "${expressionAttributeValues} ${attrValue}")
#if($foreach.hasNext)
#set($expressionAttributeNames = "${expressionAttributeNames}, ")
#end
#end
{
"TableName": "", ## Insert your table here.
"Key": { "gcn": { "S": "$input.params('')" } }, ## Insert your key expression here.
## Update below if `updatedOn` is not your audit attribute.
"UpdateExpression": "${updateExpression} updatedOn = :updatedOn",
"ExpressionAttributeNames": {$expressionAttributeNames},
"ExpressionAttributeValues": {
$expressionAttributeValues
":updatedOn": { "N": "$context.requestTimeEpoch.toString()" }
}
}
Sample Request Body:
{
"firstName": "John",
"isActive": true,
"_status": 1
}
Sample Transformation:
{
"TableName": "users",
"Key": {
"id": {
"S": "1"
}
},
"UpdateExpression": "set #firstName = :firstName, #isActive = :isActive, #_status = :_status, updatedOn = :updatedOn",
"ExpressionAttributeNames": {
"#firstName": "firstName",
"#isActive": "isActive",
"#_status": "_status"
},
"ExpressionAttributeValues": {
":firstName": {
"S": "John"
},
":isActive": {
"BOOL": true
},
":_status": {
"N": "1"
},
":updatedOn": {
"N": "123456789"
}
}
}

PEG.js help - optional free text followed by key value pairs

I wrote the following parser (paste into http://pegjs.org/online and it works):
Expression = Pairs / FullTextWithPairs
Pairs = (';'? _ p:Pair { return p; })*
FullTextWithPairs = fto:FullText po:Pairs
{
var arr = [];
if (fto) {
arr.push(fto);
}
return arr.concat(po);
}
FullText = ft:ValueString ';'
{
return {'key' : 'fullText', 'op': '=', 'value': ft};
}
Pair = k:Field op:Operator v:ValueString
{
var res = {'key' : k, 'op': op, 'value': v};
console.log(res);
return res;
}
Operator = ('<>' / [=><])
ValueString = vs:[^;]+ {return vs.join('');}
Field = 'location' / 'application' / 'count'
_ = ' '*
It parses this string of key-value pairs: location=USA; application<>app; count>5
to this:
[
{
"key": "location",
"op": "=",
"value": "USA"
},
{
"key": "application",
"op": "<>",
"value": "app"
},
{
"key": "count",
"op": ">",
"value": "5"
}
]
The problem is I want to enable a free-text search as well, which is entered before the key-value pairs, for example:
this: free text foobar; location=USA; application<>app; count>5
and get this:
[
{
"key": "fullText",
"op": "=",
"value": "free text foobar"
},
{
"key": "location",
"op": "=",
"value": "USA"
},
{
"key": "application",
"op": "<>",
"value": "app"
},
{
"key": "count",
"op": ">",
"value": "5"
}
]
The parser should recognize that the first part is not a key-value pair (according to "Pair" rule) and insert it as "fullText" object.
Basically "Expression" rule should do it, according to what I read in the docs - A / B means if A doesn't pass the B is tried. In the second case "Paris" is faild because "free text foobar" doesn't pass the Pairs rule, but it just throws an exception instead of moving on.
Congrats to whomever survived up to here, what am I doing wrong? :)
Thank you
Played with the grammar some more, the solution was to use !Pair and (for some reason) to change the order of the "Expression" rule:
Expression = FullTextWithPairs / Pairs
Pairs = (';'? _ p:Pair { return p; })*
FullTextWithPairs = fto:FullText po:Pairs
{
var arr = [];
if (fto) {
arr.push(fto);
}
return arr.concat(po);
}
FullText = !Pair ft:ValueString ';'
{
return {'key' : 'fullText', 'op': '=', 'value': ft};
}
Pair = _? k:Field op:Operator v:ValueString
{
var res = {'key' : k, 'op': op, 'value': v};
console.log(res);
return res;
}
Operator = ('<>' / [=><])
ValueString = vs:[^;]+ {return vs.join('');}
Field = 'location' / 'application' / 'count'
_ = ' '*

YouTube API returns zero results

I'm using YouTube API to retrieve videos data. I have a list of videos IDs.
For some of the videos the results that returns are normal and for some of them the API returns zero results. Via my browser all the results are valid.
Here is my code:
def getVideoDuration(self,videoId):
try:
content = urllib2.urlopen("https://www.googleapis.com/youtube/v3/videos?part=statistics%2C+contentDetails&id=" + videoId +"&key=" + self.DEVELOPER_KEY).read()
jsonContent= json.loads(content)
duration = jsonContent['items'][0].values()[0]['duration']
if len(duration) == 7:
minutes = jsonContent['items'][0].values()[0]['duration'][2]
seconds = jsonContent['items'][0].values()[0]['duration'][4:6]
if len(duration) == 5:
minutes = 0
seconds = jsonContent['items'][0].values()[0]['duration'][2:4]
print minutes,seconds
totalTime = str(minutes) + "." + str(seconds)
return float(totalTime)
except:
return 0.0
For the ID: 'fu5K2cOeD4M' my code return zero results, but via my browser the results are normal (JSON response attached):
{
"kind": "youtube#videoListResponse",
"etag": "\"0KG1mRN7bm3nResDPKHQZpg5-do/wTtZkXqw81l7Hq6-GrLwJ3wRQ5w\"",
"pageInfo": {
"totalResults": 1,
"resultsPerPage": 1
},
"items": [
{
"kind": "youtube#video",
"etag": "\"0KG1mRN7bm3nResDPKHQZpg5-do/jrxp-dHXG3s3ujaIjyq15GWV7V8\"",
"id": "fu5K2cOeD4M",
"contentDetails": {
"duration": "PT8M15S",
"dimension": "2d",
"definition": "sd",
"caption": "false",
"licensedContent": false
},
"statistics": {
"viewCount": "18358",
"likeCount": "166",
"dislikeCount": "1",
"favoriteCount": "0",
"commentCount": "33"
}
}
]
}
I tried to delay between my requests using time.sleep(), but it didn't help me.
The problem was that i sent the request i added an extra character