I know, how to use yosys compile a .dot file from a verilog .v file in order to graphically check the verilog design. I use a target like this in my makefiles:
dot:
yosys \
-p "read_verilog -sv -formal $(file_main).v" \
-p "hierarchy -check -top $(module_top)" \
-p "proc" \
-p "show -prefix $(file_main) -notitle -colors 2 -width -format dot"
xdot $(file_main).dot
But there is a problem. After .dot file is compiled and opened with `xdot everything looks more like a software flowcharts but I would like it to look more like an electronics schematics. Is there currently a way to achieve this?
I know that yosis can also create .blif files out of verilog .vfiles. I usually do it like this in my makefiles:
yosys \
-p "synth_ice40 -top $(module_top) -blif $(file_main).blif" \
$(file_main).v
Files with .blif extension are in fact a netlist files (source)! So is there any program that can somehow preview them? Or maybe a parser that can parse them so I can preview them the schematics somehow?
NETLISTSVG
There was a suggestion to use tool netlistsvg which is not actively developed and it has a nasty downside. It does not accept type inout. So If I use this makefile target:
svg:
yosys \
-p "read_verilog -sv -formal $(file_main).v" \
-p "hierarchy -check -top $(module_top)" \
-p "proc" \
-p "write_json $(file_main).json"
netlistsvg -o $(file_main).svg $(file_main).json
Yosys works great and produces the .json netlist file:
"d": {
"direction": "input",
"bits": [ 2 ]
},
"c": {
"direction": "input",
"bits": [ 3 ]
},
"r": {
"direction": "input",
"bits": [ 4 ]
},
"q": {
"direction": "inout",
"bits": [ 5 ]
}
},
"cells": {
"$and$d_flip_flop_rizing_clr.v:25$1": {
"hide_name": 1,
"type": "$and",
"parameters": {
"A_SIGNED": "00000000000000000000000000000000",
"A_WIDTH": "00000000000000000000000000000001",
"B_SIGNED": "00000000000000000000000000000000",
"B_WIDTH": "00000000000000000000000000000001",
"Y_WIDTH": "00000000000000000000000000000001"
},
"attributes": {
"src": "d_flip_flop_rizing_clr.v:25.17-25.22"
},
"port_directions": {
"A": "input",
"B": "input",
"Y": "output"
},
"connections": {
"A": [ 6 ],
"B": [ 7 ],
"Y": [ 8 ]
}
},
"$and$d_flip_flop_rizing_clr.v:26$2": {
"hide_name": 1,
"type": "$and",
"parameters": {
"A_SIGNED": "00000000000000000000000000000000",
"A_WIDTH": "00000000000000000000000000000001",
"B_SIGNED": "00000000000000000000000000000000",
"B_WIDTH": "00000000000000000000000000000001",
"Y_WIDTH": "00000000000000000000000000000001"
},
"attributes": {
"src": "d_flip_flop_rizing_clr.v:26.17-26.22"
},
"port_directions": {
"A": "input",
"B": "input",
"Y": "output"
},
"connections": {
"A": [ 9 ],
"B": [ 6 ],
"Y": [ 10 ]
}
},
"$and$d_flip_flop_rizing_clr.v:28$4": {
"hide_name": 1,
"type": "$and",
"parameters": {
"A_SIGNED": "00000000000000000000000000000000",
"A_WIDTH": "00000000000000000000000000000001",
"B_SIGNED": "00000000000000000000000000000000",
"B_WIDTH": "00000000000000000000000000000001",
"Y_WIDTH": "00000000000000000000000000000001"
},
"attributes": {
"src": "d_flip_flop_rizing_clr.v:28.17-28.25"
},
"port_directions": {
"A": "input",
"B": "input",
"Y": "output"
},
"connections": {
"A": [ 11 ],
"B": [ 9 ],
"Y": [ 12 ]
}
},
"$and$d_flip_flop_rizing_clr.v:30$6": {
"hide_name": 1,
"type": "$and",
"parameters": {
"A_SIGNED": "00000000000000000000000000000000",
"A_WIDTH": "00000000000000000000000000000001",
"B_SIGNED": "00000000000000000000000000000000",
"B_WIDTH": "00000000000000000000000000000001",
"Y_WIDTH": "00000000000000000000000000000001"
},
"attributes": {
"src": "d_flip_flop_rizing_clr.v:30.17-30.22"
},
"port_directions": {
"A": "input",
"B": "input",
"Y": "output"
},
"connections": {
"A": [ 13 ],
"B": [ 14 ],
"Y": [ 15 ]
}
},
"$and$d_flip_flop_rizing_clr.v:31$7": {
"hide_name": 1,
"type": "$and",
"parameters": {
"A_SIGNED": "00000000000000000000000000000000",
"A_WIDTH": "00000000000000000000000000000001",
"B_SIGNED": "00000000000000000000000000000000",
"B_WIDTH": "00000000000000000000000000000001",
"Y_WIDTH": "00000000000000000000000000000001"
},
"attributes": {
"src": "d_flip_flop_rizing_clr.v:31.17-31.25"
},
"port_directions": {
"A": "input",
"B": "input",
"Y": "output"
},
"connections": {
"A": [ 15 ],
"B": [ 2 ],
"Y": [ 16 ]
}
},
"$and$d_flip_flop_rizing_clr.v:34$10": {
"hide_name": 1,
"type": "$and",
"parameters": {
"A_SIGNED": "00000000000000000000000000000000",
"A_WIDTH": "00000000000000000000000000000001",
"B_SIGNED": "00000000000000000000000000000000",
"B_WIDTH": "00000000000000000000000000000001",
"Y_WIDTH": "00000000000000000000000000000001"
},
"attributes": {
"src": "d_flip_flop_rizing_clr.v:34.17-34.22"
},
"port_directions": {
"A": "input",
"B": "input",
"Y": "output"
},
"connections": {
"A": [ 13 ],
"B": [ 14 ],
"Y": [ 17 ]
}
},
"$and$d_flip_flop_rizing_clr.v:35$11": {
"hide_name": 1,
"type": "$and",
"parameters": {
"A_SIGNED": "00000000000000000000000000000000",
"A_WIDTH": "00000000000000000000000000000001",
"B_SIGNED": "00000000000000000000000000000000",
"B_WIDTH": "00000000000000000000000000000001",
"Y_WIDTH": "00000000000000000000000000000001"
},
"attributes": {
"src": "d_flip_flop_rizing_clr.v:35.17-35.25"
},
"port_directions": {
"A": "input",
"B": "input",
"Y": "output"
},
"connections": {
"A": [ 17 ],
"B": [ 5 ],
"Y": [ 18 ]
}
},
"$and$d_flip_flop_rizing_clr.v:37$13": {
"hide_name": 1,
"type": "$and",
"parameters": {
"A_SIGNED": "00000000000000000000000000000000",
"A_WIDTH": "00000000000000000000000000000001",
"B_SIGNED": "00000000000000000000000000000000",
"B_WIDTH": "00000000000000000000000000000001",
"Y_WIDTH": "00000000000000000000000000000001"
},
"attributes": {
"src": "d_flip_flop_rizing_clr.v:37.17-37.22"
},
"port_directions": {
"A": "input",
"B": "input",
"Y": "output"
},
"connections": {
"A": [ 19 ],
"B": [ 14 ],
"Y": [ 20 ]
}
},
"$and$d_flip_flop_rizing_clr.v:38$14": {
"hide_name": 1,
"type": "$and",
"parameters": {
"A_SIGNED": "00000000000000000000000000000000",
"A_WIDTH": "00000000000000000000000000000001",
"B_SIGNED": "00000000000000000000000000000000",
"B_WIDTH": "00000000000000000000000000000001",
"Y_WIDTH": "00000000000000000000000000000001"
},
"attributes": {
"src": "d_flip_flop_rizing_clr.v:38.17-38.25"
},
"port_directions": {
"A": "input",
"B": "input",
"Y": "output"
},
"connections": {
"A": [ 20 ],
"B": [ 3 ],
"Y": [ 21 ]
}
},
"$and$d_flip_flop_rizing_clr.v:41$17": {
"hide_name": 1,
"type": "$and",
"parameters": {
"A_SIGNED": "00000000000000000000000000000000",
"A_WIDTH": "00000000000000000000000000000001",
"B_SIGNED": "00000000000000000000000000000000",
"B_WIDTH": "00000000000000000000000000000001",
"Y_WIDTH": "00000000000000000000000000000001"
},
"attributes": {
"src": "d_flip_flop_rizing_clr.v:41.17-41.22"
},
"port_directions": {
"A": "input",
"B": "input",
"Y": "output"
},
"connections": {
"A": [ 6 ],
"B": [ 3 ],
"Y": [ 11 ]
}
},
"$not$d_flip_flop_rizing_clr.v:27$3": {
"hide_name": 1,
"type": "$not",
"parameters": {
"A_SIGNED": "00000000000000000000000000000000",
"A_WIDTH": "00000000000000000000000000000001",
"Y_WIDTH": "00000000000000000000000000000001"
},
"attributes": {
"src": "d_flip_flop_rizing_clr.v:27.17-27.23"
},
"port_directions": {
"A": "input",
"Y": "output"
},
"connections": {
"A": [ 8 ],
"Y": [ 5 ]
}
},
"$not$d_flip_flop_rizing_clr.v:29$5": {
"hide_name": 1,
"type": "$not",
"parameters": {
"A_SIGNED": "00000000000000000000000000000000",
"A_WIDTH": "00000000000000000000000000000001",
"Y_WIDTH": "00000000000000000000000000000001"
},
"attributes": {
"src": "d_flip_flop_rizing_clr.v:29.14-29.20"
},
"port_directions": {
"A": "input",
"Y": "output"
},
"connections": {
"A": [ 12 ],
"Y": [ 13 ]
}
},
"$not$d_flip_flop_rizing_clr.v:32$8": {
"hide_name": 1,
"type": "$not",
"parameters": {
"A_SIGNED": "00000000000000000000000000000000",
"A_WIDTH": "00000000000000000000000000000001",
"Y_WIDTH": "00000000000000000000000000000001"
},
"attributes": {
"src": "d_flip_flop_rizing_clr.v:32.14-32.20"
},
"port_directions": {
"A": "input",
"Y": "output"
},
"connections": {
"A": [ 16 ],
"Y": [ 9 ]
}
},
"$not$d_flip_flop_rizing_clr.v:33$9": {
"hide_name": 1,
"type": "$not",
"parameters": {
"A_SIGNED": "00000000000000000000000000000000",
"A_WIDTH": "00000000000000000000000000000001",
"Y_WIDTH": "00000000000000000000000000000001"
},
"attributes": {
"src": "d_flip_flop_rizing_clr.v:33.14-33.17"
},
"port_directions": {
"A": "input",
"Y": "output"
},
"connections": {
"A": [ 4 ],
"Y": [ 14 ]
}
},
"$not$d_flip_flop_rizing_clr.v:36$12": {
"hide_name": 1,
"type": "$not",
"parameters": {
"A_SIGNED": "00000000000000000000000000000000",
"A_WIDTH": "00000000000000000000000000000001",
"Y_WIDTH": "00000000000000000000000000000001"
},
"attributes": {
"src": "d_flip_flop_rizing_clr.v:36.14-36.20"
},
"port_directions": {
"A": "input",
"Y": "output"
},
"connections": {
"A": [ 18 ],
"Y": [ 7 ]
}
},
"$not$d_flip_flop_rizing_clr.v:39$15": {
"hide_name": 1,
"type": "$not",
"parameters": {
"A_SIGNED": "00000000000000000000000000000000",
"A_WIDTH": "00000000000000000000000000000001",
"Y_WIDTH": "00000000000000000000000000000001"
},
"attributes": {
"src": "d_flip_flop_rizing_clr.v:39.14-39.20"
},
"port_directions": {
"A": "input",
"Y": "output"
},
"connections": {
"A": [ 21 ],
"Y": [ 6 ]
}
},
"$not$d_flip_flop_rizing_clr.v:40$16": {
"hide_name": 1,
"type": "$not",
"parameters": {
"A_SIGNED": "00000000000000000000000000000000",
"A_WIDTH": "00000000000000000000000000000001",
"Y_WIDTH": "00000000000000000000000000000001"
},
"attributes": {
"src": "d_flip_flop_rizing_clr.v:40.14-40.20"
},
"port_directions": {
"A": "input",
"Y": "output"
},
"connections": {
"A": [ 10 ],
"Y": [ 19 ]
}
}
},
"netnames": {
"$and$d_flip_flop_rizing_clr.v:25$1_Y": {
"hide_name": 1,
"bits": [ 8 ],
"attributes": {
"src": "d_flip_flop_rizing_clr.v:25.17-25.22"
}
},
"$and$d_flip_flop_rizing_clr.v:26$2_Y": {
"hide_name": 1,
"bits": [ 10 ],
"attributes": {
"src": "d_flip_flop_rizing_clr.v:26.17-26.22"
}
},
"$and$d_flip_flop_rizing_clr.v:28$4_Y": {
"hide_name": 1,
"bits": [ 12 ],
"attributes": {
"src": "d_flip_flop_rizing_clr.v:28.17-28.25"
}
},
"$and$d_flip_flop_rizing_clr.v:30$6_Y": {
"hide_name": 1,
"bits": [ 15 ],
"attributes": {
"src": "d_flip_flop_rizing_clr.v:30.17-30.22"
}
},
"$and$d_flip_flop_rizing_clr.v:31$7_Y": {
"hide_name": 1,
"bits": [ 16 ],
"attributes": {
"src": "d_flip_flop_rizing_clr.v:31.17-31.25"
}
},
"$and$d_flip_flop_rizing_clr.v:34$10_Y": {
"hide_name": 1,
"bits": [ 17 ],
"attributes": {
"src": "d_flip_flop_rizing_clr.v:34.17-34.22"
}
},
"$and$d_flip_flop_rizing_clr.v:35$11_Y": {
"hide_name": 1,
"bits": [ 18 ],
"attributes": {
"src": "d_flip_flop_rizing_clr.v:35.17-35.25"
}
},
"$and$d_flip_flop_rizing_clr.v:37$13_Y": {
"hide_name": 1,
"bits": [ 20 ],
"attributes": {
"src": "d_flip_flop_rizing_clr.v:37.17-37.22"
}
},
"$and$d_flip_flop_rizing_clr.v:38$14_Y": {
"hide_name": 1,
"bits": [ 21 ],
"attributes": {
"src": "d_flip_flop_rizing_clr.v:38.17-38.25"
}
},
"$and$d_flip_flop_rizing_clr.v:41$17_Y": {
"hide_name": 1,
"bits": [ 11 ],
"attributes": {
"src": "d_flip_flop_rizing_clr.v:41.17-41.22"
}
},
"$not$d_flip_flop_rizing_clr.v:27$3_Y": {
"hide_name": 1,
"bits": [ 5 ],
"attributes": {
"src": "d_flip_flop_rizing_clr.v:27.17-27.23"
}
},
"$not$d_flip_flop_rizing_clr.v:29$5_Y": {
"hide_name": 1,
"bits": [ 13 ],
"attributes": {
"src": "d_flip_flop_rizing_clr.v:29.14-29.20"
}
},
"$not$d_flip_flop_rizing_clr.v:32$8_Y": {
"hide_name": 1,
"bits": [ 9 ],
"attributes": {
"src": "d_flip_flop_rizing_clr.v:32.14-32.20"
}
},
"$not$d_flip_flop_rizing_clr.v:33$9_Y": {
"hide_name": 1,
"bits": [ 14 ],
"attributes": {
"src": "d_flip_flop_rizing_clr.v:33.14-33.17"
}
},
"$not$d_flip_flop_rizing_clr.v:36$12_Y": {
"hide_name": 1,
"bits": [ 7 ],
"attributes": {
"src": "d_flip_flop_rizing_clr.v:36.14-36.20"
}
},
"$not$d_flip_flop_rizing_clr.v:39$15_Y": {
"hide_name": 1,
"bits": [ 6 ],
"attributes": {
"src": "d_flip_flop_rizing_clr.v:39.14-39.20"
}
},
"$not$d_flip_flop_rizing_clr.v:40$16_Y": {
"hide_name": 1,
"bits": [ 19 ],
"attributes": {
"src": "d_flip_flop_rizing_clr.v:40.14-40.20"
}
},
"_00_": {
"hide_name": 0,
"bits": [ 5 ],
"attributes": {
"src": "d_flip_flop_rizing_clr.v:4.8-4.12"
}
},
"_01_": {
"hide_name": 0,
"bits": [ 12 ],
"attributes": {
"src": "d_flip_flop_rizing_clr.v:5.8-5.12"
}
},
"_02_": {
"hide_name": 0,
"bits": [ 15 ],
"attributes": {
"src": "d_flip_flop_rizing_clr.v:6.8-6.12"
}
},
"_03_": {
"hide_name": 0,
"bits": [ 16 ],
"attributes": {
"src": "d_flip_flop_rizing_clr.v:7.8-7.12"
}
},
"_04_": {
"hide_name": 0,
"bits": [ 17 ],
"attributes": {
"src": "d_flip_flop_rizing_clr.v:8.8-8.12"
}
},
"_05_": {
"hide_name": 0,
"bits": [ 18 ],
"attributes": {
"src": "d_flip_flop_rizing_clr.v:9.8-9.12"
}
},
"_06_": {
"hide_name": 0,
"bits": [ 20 ],
"attributes": {
"src": "d_flip_flop_rizing_clr.v:10.8-10.12"
}
},
"_07_": {
"hide_name": 0,
"bits": [ 21 ],
"attributes": {
"src": "d_flip_flop_rizing_clr.v:11.8-11.12"
}
},
"_08_": {
"hide_name": 0,
"bits": [ 11 ],
"attributes": {
"src": "d_flip_flop_rizing_clr.v:12.8-12.12"
}
},
"_09_": {
"hide_name": 0,
"bits": [ 8 ],
"attributes": {
"src": "d_flip_flop_rizing_clr.v:13.8-13.12"
}
},
"_10_": {
"hide_name": 0,
"bits": [ 10 ],
"attributes": {
"src": "d_flip_flop_rizing_clr.v:14.8-14.12"
}
},
"c": {
"hide_name": 0,
"bits": [ 3 ],
"attributes": {
"src": "d_flip_flop_rizing_clr.v:15.9-15.10"
}
},
"d": {
"hide_name": 0,
"bits": [ 2 ],
"attributes": {
"src": "d_flip_flop_rizing_clr.v:16.9-16.10"
}
},
"e": {
"hide_name": 0,
"bits": [ 14 ],
"attributes": {
"src": "d_flip_flop_rizing_clr.v:17.8-17.9"
}
},
"f": {
"hide_name": 0,
"bits": [ 19 ],
"attributes": {
"src": "d_flip_flop_rizing_clr.v:18.8-18.9"
}
},
"g": {
"hide_name": 0,
"bits": [ 6 ],
"attributes": {
"src": "d_flip_flop_rizing_clr.v:19.8-19.9"
}
},
"h": {
"hide_name": 0,
"bits": [ 13 ],
"attributes": {
"src": "d_flip_flop_rizing_clr.v:20.8-20.9"
}
},
"i": {
"hide_name": 0,
"bits": [ 9 ],
"attributes": {
"src": "d_flip_flop_rizing_clr.v:21.8-21.9"
}
},
"j": {
"hide_name": 0,
"bits": [ 7 ],
"attributes": {
"src": "d_flip_flop_rizing_clr.v:22.8-22.9"
}
},
"q": {
"hide_name": 0,
"bits": [ 5 ],
"attributes": {
"src": "d_flip_flop_rizing_clr.v:23.9-23.10"
}
},
"r": {
"hide_name": 0,
"bits": [ 4 ],
"attributes": {
"src": "d_flip_flop_rizing_clr.v:24.9-24.10"
}
}
}
}
}
}
But tha netlistsvg command fails with an error:
netlistsvg -o d_flip_flop_rizing_clr.svg d_flip_flop_rizing_clr.json
/usr/local/lib/node_modules/netlistsvg/bin/netlistsvg.js:55
throw Error(JSON.stringify(ajv.errors, null, 2));
^
Error: [
{
"keyword": "enum",
"dataPath": "/modules/d_flip_flop_rizing_clr/ports/q/direction",
"schemaPath": "#/properties/modules/additionalProperties/properties/ports/additionalProperties/properties/direction/enum",
"params": {
"allowedValues": [
"input",
"output"
]
},
"message": "should be equal to one of the allowed values"
}
]
at /usr/local/lib/node_modules/netlistsvg/bin/netlistsvg.js:55:19
at /usr/local/lib/node_modules/netlistsvg/bin/netlistsvg.js:41:17
at FSReqCallback.readFileAfterClose [as oncomplete] (internal/fs/read_file_context.js:63:3)
make: *** [makefile:152: svg] Error 1
And it is complaining about inout type. Very incomplete...
You might want to have a look at NetlistSVG. It can draw a schematic from a JSON netlist created by Yosys.
Related
Hello,
I'm new in Talend. Want to extract data from file to table format.
What will steps to retrieve data in column format from below data -( _id,projectName,title,value)
Array data -
[
{
"_id": 1,
"projectName": "Test",
"languageId": 1,
"userId": 100,
"userDetails": {
"location": {
"coordinates": [
19.2666415,
72.9814762
]
},
"serialNumber": "5ab24f2d2ce1"
},
"questionDetails": [
{
"_id": 1,
"title": "QuestionName 01",
"description": "QuestionName 01",
"question": "QuestionName 01",
"type": "Radio",
"optionMap": {
"1": "Option 01",
"2": "Option 01"
},
"response": {
"value": [
"2"
]
},
"responseExtension": {
"comments": "",
"reviews": "",
"summary": "",
"imageURLs": [
],
"videoURLs": [
],
"audioURLs": [
]
}
}
],
"createdDate": {
"$date": {
"$numberLong": "1603802807000"
}
},
"lastModifiedDate": {
"$date": {
"$numberLong": "1603802807000"
}
},
"_class": "dummy"
},
{
"_id": 2,
"projectName": "Test",
"languageId": 1,
"userId": 101,
"surveyId": 1,
"sectionId": 10,
"userDetails": {
"location": {
"coordinates": [
19.0564471,
72.9033019
]
},
"serialNumber": "d8ee581588c2"
},
"questionDetails": [
{
"_id": 11,
"title": "QuestionName 02",
"description": "QuestionName 02",
"question": "QuestionName 02",
"type": "Radio",
"optionMap": {
"1": "Option 02",
"2": "Option 02"
},
"response": {
"value": [
"1"
]
},
"responseExtension": {
"comments": "",
"reviews": "",
"summary": "",
"imageURLs": [
],
"videoURLs": [
],
"audioURLs": [
]
}
}
],
"isActive": false,
"communication": {
},
"questionIndex": 0,
"isAboutToFinish": false,
"managingStatus": "archived",
"sectionIds": [
],
"questionResponses": [
],
"createdDate": {
"$date": {
"$numberLong": "1603372059000"
}
},
"lastModifiedDate": {
"$date": {
"$numberLong": "1658313691000"
}
},
"_class": "dummy"
}
]
I want to filter out only entries from a list "NestedRecords" inside each "Record" entry.
Let's say I have these Id's of nested records which should be returned:
nestedRecordsToBeReturned = [1,3]
This is the given table with records and nestedRecords inside each record:
{
"Records": [
{
"Record": "record1",
"NestedRecords": [
{
"id": 1,
"label": "l1"
},
{
"id": 2,
"label": "l2"
},
{
"id": 3,
"label": "l3"
},
{
"id": 4,
"label": "l4"
},
{
"id": 6,
"label": "l6"
}
]
},
{
"Record": "record2",
"Records": [
{
"id": 1,
"label": "l1"
},
{
"id": 2,
"label": "l2"
},
{
"id": 4,
"label": "l4"
},
{
"id": 7,
"label": "l7"
}
]
},
{
"Record": "record3",
"Records": [
{
"id": 2,
"label": "l2"
},
{
"id": 3,
"label": "l3"
},
{
"id": 9,
"label": "l9"
},
{
"id": 10,
"label": "l10"
}
]
}
]
}
This is what I want to be returned:
{
"Records": [
{
"Record": "record1",
"NestedRecords": [
{
"id": 1,
"label": "l1"
},
{
"id": 3,
"label": "l3"
},
]
},
{
"Record": "record2",
"Records": [
{
"id": 1,
"label": "l1"
},
]
},
{
"Record": "record3",
"Records": [
{
"id": 3,
"label": "l3"
},
]
}
]
}
How do I achieve this with an elastic query?
Is it even possible to filter a list which is embedded in a document?
I play a game which uses skins, around 200'000 of them and the players struggle to find them since there isn't really a search function other than random names.
Each skin has a name chosen by the users who upload them and that's it, others don't know about it untill they see it used by someone else.
I made some tools to make it easier and I wanted to implement a search by tag function, for example you search "dog" and it gives you the skins containing dogs. Is there a program able to automatically give tags to 200k images?
Game: https://Gota.io
My "tool"(badly made website) https://specy.it/SkinGallery.html
And the extension for the game: https://www.dropbox.com/s/36w6dkz22pxksrz/Extension.js?dl=0
This is not my specialty and it's an evolving field, but for the time being there are "image recognition as a service" services such as Google Vision whose rest API you can use to have the machine tag your image according to what it sees.
That being said, I'm not sure if your skins are suit for a good result. If we try it on the "dead mickey" skin, we get:
Well yeah, there's an animal, I guess. If you look at the "labels" tab you'd see it describes mostly colors, but it also mentions "fictional character" in the 12th place or so.
Depending on the skin, different contexts could suit you better. For example, if you use Sage Mode Naruto, Objects, Labels and Logos bring very little information, but Web tab says:
How would you handle the response of the rest service? Well, it's a JSON with the form:
{
"cropHintsAnnotation": {
"cropHints": [...]
},
"fullTextAnnotation": {
"pages": [
{
"blocks": [...],
"height": 512,
"property": {
"detectedLanguages": [
{
"confidence": 0.88,
"languageCode": "en"
}
]
},
"width": 512
}
],
"text": "SUH DUDE\n.\n"
},
"imagePropertiesAnnotation": {
"cropHints": [...],
"dominantColors": {
"colors": [...]
}
},
"labelAnnotations": [
{
"description": "Illustration",
"mid": "/m/01kr8f",
"score": 0.8927454,
"topicality": 0.8927454
},
{
"description": "Cartoon",
"mid": "/m/0215n",
"score": 0.8583309,
"topicality": 0.8583309
},
{
"description": "Circle",
"mid": "/m/01vkl",
"score": 0.70432633,
"topicality": 0.70432633
},
{
"description": "Art",
"mid": "/m/0jjw",
"score": 0.6253477,
"topicality": 0.6253477
},
{
"description": "Clip art",
"mid": "/m/03g09t",
"score": 0.5876344,
"topicality": 0.5876344
},
{
"description": "Fictional character",
"mid": "/m/02h7lkt",
"score": 0.52791756,
"topicality": 0.52791756
}
],
"localizedObjectAnnotations": [...],
"logoAnnotations": [...],
"description": "Los Angeles Rams",
"mid": "/m/06x76",
"score": 0.5958965
}
],
"safeSearchAnnotation": {
"adult": "VERY_UNLIKELY",
"medical": "VERY_UNLIKELY",
"racy": "VERY_UNLIKELY",
"spoof": "VERY_UNLIKELY",
"violence": "VERY_UNLIKELY"
},
"textAnnotations": [...],
{
"boundingPoly": {
"vertices": [
{
"x": 182,
"y": 40
},
{
"x": 295,
"y": 40
},
{
"x": 295,
"y": 111
},
{
"x": 182,
"y": 111
}
]
},
"description": "SUH DUDE\n.\n",
"locale": "en"
},
{
"boundingPoly": {
"vertices": [
{
"x": 182,
"y": 44
},
{
"x": 222,
"y": 43
},
{
"x": 223,
"y": 66
},
{
"x": 183,
"y": 67
}
]
},
"description": "SUH"
},
{
"boundingPoly": {
"vertices": [
{
"x": 237,
"y": 42
},
{
"x": 294,
"y": 40
},
{
"x": 295,
"y": 64
},
{
"x": 238,
"y": 66
}
]
},
"description": "DUDE"
},
{
"boundingPoly": {
"vertices": [
{
"x": 194,
"y": 101
},
{
"x": 196,
"y": 100
},
{
"x": 200,
"y": 111
},
{
"x": 198,
"y": 111
}
]
},
"description": "."
}
"webDetection": {
"bestGuessLabels": [
{
"label": "cartoon"
}
],
"pagesWithMatchingImages": [
{
"pageTitle": "edit #anime #naruto #foryou #foryoupage #narutouzumaki ... - TikTok",
"partialMatchingImages": [
{
"url": "https://p16.muscdn.com/obj/tos-maliva-p-0068/b27c516d2faee4174d0e4a26b7a3d466"
}
],
"url": "https://www.tiktok.com/#sakura._.haruno_editz/video/6777103057055517958?lang=en"
},
{
"pageTitle": "Originalton - edix_official TikTok Music Videos • TikyToky",
"partialMatchingImages": [
{
"url": "https://p16.muscdn.com/obj/tos-maliva-p-0068/b27c516d2faee4174d0e4a26b7a3d466"
}
],
"url": "https://tikytoky.com/music/originalton-6768700410359302918"
},
{
"pageTitle": ".... Wanna gain tons of followers? Follow #dragonballexclusives ...",
"partialMatchingImages": [
{
"url": "https://scontent-frt3-1.cdninstagram.com/vp/cdb9be9aa9707b90d55564a965668b7c/5E881986/t51.2885-19/s150x150/71524634_2513191889001976_2699215275693178880_n.jpg?_nc_ht=scontent-frt3-1.cdninstagram.com"
}
],
"url": "https://www.mystalk.net/detail/1917580489812869720_7212599026"
},
{
"pageTitle": "edit #anime #naruto #foryou #foryoupage #narutouzumaki ... - TikTok",
"partialMatchingImages": [
{
"url": "https://p16.muscdn.com/obj/tos-maliva-p-0068/b27c516d2faee4174d0e4a26b7a3d466"
}
],
"url": "https://www.tiktok.com/#sakura._.haruno_editz/video/6777103057055517958?region=KR&langCountry=pa&source=h5_t&lang=ar"
},
{
"pageTitle": "edit #anime #naruto #foryou #foryoupage #narutouzumaki ... - TikTok",
"partialMatchingImages": [
{
"url": "https://p16.muscdn.com/obj/tos-maliva-p-0068/b27c516d2faee4174d0e4a26b7a3d466"
}
],
"url": "https://www.tiktok.com/#sakura._.haruno_editz/video/6777103057055517958?region=KR&langCountry=pa&source=h5_t&lang=en"
},
{
"pageTitle": "edit #anime #naruto #foryou #foryoupage #narutouzumaki ... - TikTok",
"partialMatchingImages": [
{
"url": "https://p16.muscdn.com/obj/tos-maliva-p-0068/b27c516d2faee4174d0e4a26b7a3d466"
}
],
"url": "https://www.tiktok.com/#sakura._.haruno_editz/video/6777103057055517958?region=JP&langCountry=ja"
},
{
"pageTitle": "edit #anime #naruto #foryou #foryoupage #narutouzumaki ... - TikTok",
"partialMatchingImages": [
{
"url": "https://p16.muscdn.com/obj/tos-maliva-p-0068/b27c516d2faee4174d0e4a26b7a3d466"
}
],
"url": "https://www.tiktok.com/#sakura._.haruno_editz/video/6777103057055517958?lang=de"
}
],
"partialMatchingImages": [
{
"url": "https://p16.muscdn.com/obj/tos-maliva-p-0068/b27c516d2faee4174d0e4a26b7a3d466"
},
{
"url": "https://scontent-frt3-1.cdninstagram.com/vp/cdb9be9aa9707b90d55564a965668b7c/5E881986/t51.2885-19/s150x150/71524634_2513191889001976_2699215275693178880_n.jpg?_nc_ht=scontent-frt3-1.cdninstagram.com"
}
],
"visuallySimilarImages": [
{
"url": "https://previews.123rf.com/images/lenm/lenm1703/lenm170300080/73206609-sketchy-illustration-featuring-a-woman-looking-fondly-at-her-baby-strapped-to-a-carrier.jpg"
},
{
"url": "https://media.gettyimages.com/vectors/cartoon-soccer-football-girl-character-vector-id487299807"
},
{
"url": "https://pbs.twimg.com/profile_images/1062176350797066241/UhaIkhRy_400x400.jpg"
},
{
"url": "https://img.favpng.com/1/13/23/vertebrate-line-art-cartoon-clip-art-png-favpng-2LN24w4JHvqm4VfaF0gq56thE_t.jpg"
},
{
"url": "https://f1.pngfuel.com/png/337/556/27/smile-human-cartoon-character-pink-m-happiness-behavior-purple-png-clip-art-thumbnail.png"
},
{
"url": "https://img.favpng.com/8/3/13/clip-art-illustration-dance-hula-vector-graphics-png-favpng-jPQ56XsgP7Gi2cMLzhxbFApeA_t.jpg"
},
{
"url": "https://img.favpng.com/16/4/23/clip-art-pre-school-illustration-human-behavior-png-favpng-VEBwHZmyxNijn756GP0YUW6BV_t.jpg"
},
{
"url": "https://cdn.imgbin.com/11/5/20/imgbin-blond-girl-woman-blonde-haired-s-vPKgK1yAr3Z1vhLcyBms7tCL0.jpg"
},
{
"url": "https://thumbnail.imgbin.com/3/13/22/imgbin-homo-sapiens-woman-cartoon-gipsy-nCHD5ktXjAryu06DKrqc4cZmR_t.jpg"
},
{
"url": "http://clipartmag.com/images/shocked-clipart-1.jpg"
},
{
"url": "https://i.pinimg.com/236x/10/89/7a/10897abb60aeafad127c8e80c5732001--doodle-kids-muslim-fashion.jpg"
},
{
"url": "https://art.pixilart.com/thumb/0721b071d8ec62a.png"
},
{
"url": "https://img.favpng.com/0/4/24/detective-cartoon-png-favpng-7t1LwLmVSieejTCmm39qDLgQV_t.jpg"
}
],
"webEntities": [
{
"description": "Hinata Hyuga",
"entityId": "/m/04b5nh",
"score": 0.32295
},
{
"description": "Naruto Uzumaki",
"entityId": "/m/02sp46",
"score": 0.31364998
},
{
"description": "Sakura Haruno",
"entityId": "/m/037b28",
"score": 0.30705
},
{
"description": "Naruto",
"entityId": "/m/01hryy",
"score": 0.2758
},
{
"description": "Illustration",
"entityId": "/m/01kr8f",
"score": 0.2729761
},
{
"description": "Cartoon",
"entityId": "/m/0215n",
"score": 0.25171754
},
{
"description": "TikTok",
"entityId": "/g/11f555cn8l",
"score": 0.2241
},
{
"description": "Anime",
"entityId": "/m/0jxy",
"score": 0.207
},
{
"description": "Text",
"entityId": "/m/07s6nbt",
"score": 0.19760928
},
{
"description": "Music video",
"entityId": "/m/0mdxd",
"score": 0.187
},
{
"description": "Dragon Ball",
"entityId": "/m/0k2dm",
"score": 0.1776
},
{
"description": "Character",
"entityId": "/m/0k5v2",
"score": 0.1657
},
{
"description": "Fiction",
"entityId": "/m/02xlf",
"score": 0.1247
}
]
}
}
The image above lists the terms under webDetection -> webEntities.
However, there's no one size fits all. Those terms are irrelevant in mickey's skin), whose tags, albeit loose, should be the ones under localizedObjectAnnotations or labelAnnotations. It would need human moderation to provide real value.
Of course, if you have no tags whatsoever, adding some groups from the response without human moderation would be better than nothing.
Other services from big players you can look at:
Watson Image Recognition (IBM)
Amazon Rekognition
Google added the option to request specific fields in their 'Place Details' api.
I've added the fields that I want to the request params and I'm still getting all the fields even though I didn't request some of them.
my request URL :
https://maps.googleapis.com/maps/api/place/details/json?placeid=ChIJ022Et4sG5xQRtB0kHxBfakc&key=*****&fileds=address_component,adr_address,alt_id,formatted_address,geometry,icon,id,name,permanently_closed,photo,place_id,plus_code,scope,type,url,utc_offset,vicinity
and this is the response :
{
"html_attributions": [],
"result": {
"address_components": [
{
"long_name": "8021",
"short_name": "8021",
"types": [
"street_number"
]
},
{
"long_name": "Ελευθέριου Βενιζέλου",
"short_name": "Ελευθέριου Βενιζέλου",
"types": [
"route"
]
},
{
"long_name": "Baf",
"short_name": "Baf",
"types": [
"locality",
"political"
]
},
{
"long_name": "Baf",
"short_name": "Baf",
"types": [
"administrative_area_level_1",
"political"
]
},
{
"long_name": "Cyprus",
"short_name": "CY",
"types": [
"country",
"political"
]
}
],
"adr_address": "56, <span class=\"street-address\">Ελευθέριου Βενιζέλου 8021</span>, <span class=\"locality\">Baf</span>, <span class=\"country-name\">Cyprus</span>",
"formatted_address": "56, Ελευθέριου Βενιζέλου 8021, Baf, Cyprus",
"formatted_phone_number": "26 944855",
"geometry": {
"location": {
"lat": 34.7810935,
"lng": 32.4350841
},
"viewport": {
"northeast": {
"lat": 34.7824810802915,
"lng": 32.43649373029149
},
"southwest": {
"lat": 34.7797831197085,
"lng": 32.4337957697085
}
}
},
"icon": "https://maps.gstatic.com/mapfiles/place_api/icons/restaurant-71.png",
"id": "108c7a1119ccc7ecfff72825a5df8bbd6a025192",
"international_phone_number": "+357 26 944855",
"name": "New York Sweets",
"opening_hours": {
"open_now": true,
"periods": [
{
"close": {
"day": 0,
"time": "2100"
},
"open": {
"day": 0,
"time": "0900"
}
},
{
"close": {
"day": 1,
"time": "2100"
},
"open": {
"day": 1,
"time": "0900"
}
},
{
"close": {
"day": 2,
"time": "2100"
},
"open": {
"day": 2,
"time": "0900"
}
},
{
"close": {
"day": 3,
"time": "2100"
},
"open": {
"day": 3,
"time": "0900"
}
},
{
"close": {
"day": 4,
"time": "2100"
},
"open": {
"day": 4,
"time": "0900"
}
},
{
"close": {
"day": 5,
"time": "2100"
},
"open": {
"day": 5,
"time": "0900"
}
},
{
"close": {
"day": 6,
"time": "2100"
},
"open": {
"day": 6,
"time": "0900"
}
}
],
"weekday_text": [
"Monday: 9:00 AM – 9:00 PM",
"Tuesday: 9:00 AM – 9:00 PM",
"Wednesday: 9:00 AM – 9:00 PM",
"Thursday: 9:00 AM – 9:00 PM",
"Friday: 9:00 AM – 9:00 PM",
"Saturday: 9:00 AM – 9:00 PM",
"Sunday: 9:00 AM – 9:00 PM"
]
},
"photos": [
{
"height": 854,
"html_attributions": [
"Michalis Christofi"
],
"photo_reference": "CmRZAAAAlKTZ5eOmQlupJ-rP71RW8djD8EDVCjb4xWGwpBH0fwBVtZwnnuYxitbabXV_aYTID0clGnlDR0SibQGsOW6i79-tEe-b69qZQ2Y_2k3lW1zpLcP_wrgXANvyKSzbW23XEhB8gIuRI2uYOsmDMpF_L4CsGhR0PpCS20QRffwv3q6MS6HKg4sbdA",
"width": 640
},
{
"height": 960,
"html_attributions": [
"Michalis Christofi"
],
"photo_reference": "CmRZAAAA715GtCYdgW4fChR9bsEdKJCyqspxFxNaw-wARuswoT4Vi_NC88Cg7LFQIfGAvWUSuKOhmDXBFzGZgOgRdGVjLWmuPUiIV1dMo2BJU2AJH5hpimiDVA2k0CtNwbTAmra1EhBhNKEDAVnd7RJtfkTEvO5NGhS3a9G8XQG16NVHdUGIpgtqv9ZlZw",
"width": 899
},
{
"height": 720,
"html_attributions": [
"Андрей Тихонов"
],
"photo_reference": "CmRaAAAA1VB5gyNfgeKnHRd_3hEPtcn-ddhHAQFZndcEeLu_w3N1IvtbDtViJfQ-Gjcu_ptCPigLsc3yFUl8cxRruT6ZJpFrMKSbLh544NQqAD72iQmpkpUNm9gy-2J6uAz4g0y2EhBlOHhkFM2RyQbHp8ut9gW7GhSnI2JrjLRNQ7TrZojJebjVLuqUtg",
"width": 1280
},
{
"height": 1463,
"html_attributions": [
"Michalis Christofi"
],
"photo_reference": "CmRZAAAAJjNiiWBeg0Q4HaqSBg_ndJ7XFugVSKj8_PYkUvWgcwVQaVc3RTTIoShDokWLrEPOS7GV-vilqjTXgmSlQdN_Ju3kXLXWNHkEsnZA3d_EdxieXb4q2KbsWiTVYYmoqK2TEhAyOm3gfdARi6Gz96oaQhr2GhTZK9cSie3dHNUr_GyR3dNCLk8x9g",
"width": 2000
},
{
"height": 854,
"html_attributions": [
"Michalis Christofi"
],
"photo_reference": "CmRZAAAAPJ3QX0KjX4QFr1NP9H8uyvONNmo95dlbLN5sj6r_65-dzlHfS0_G5wLf3BISu7lIIe8Zzg0DtYcq8l6E1vl-x7vuwsJAGp4Oixn6OoO3BXNKrsJPFc9A5dyxoLqXnjkeEhDS3ZN3V2LMgKB5HTQx4Oq4GhTyuViljWaU_wvEADhvdaoviV05pw",
"width": 640
},
{
"height": 960,
"html_attributions": [
"Michalis Christofi"
],
"photo_reference": "CmRZAAAA62cqSZn29xr9xtwS2-V2Mgpkxr_uv95zrQbJiQf4D185roywoZhnJMgn4l8UfVdE_DNlBd_OfEJNmt63Ul36G9McPVFh22-k67BSsa6G_GdYl4wOFuAI0hwnp_B0P7dXEhAvKR890R42YW0OJ_CSAFijGhTlkOOdJttXHGLcHXDRQtJb8Cyeuw",
"width": 720
},
{
"height": 921,
"html_attributions": [
"Michalis Christofi"
],
"photo_reference": "CmRZAAAAB9UnZE_v6khkk1Kdp7vb9V6kK1xw-_H-b5JaASutS-8VNvM8Fk9WkNrpH4NbDkq6rjfBdRJsRE3EX5_31AqU0rWpNL18kvAvNsVafPhuDk5qtxECnTnR0P31NZV5Mv2OEhCTV1AQFseaaV-SWnMNHDa9GhR5cywSvCIs9OFAB-OmZJSdp8ZoUQ",
"width": 960
},
{
"height": 1152,
"html_attributions": [
"Michalis Christofi"
],
"photo_reference": "CmRZAAAABY8bl7qB-3mI7Q5JUsco0xHp8vJLMyCf8SINMu8TDpIq9pUq1w3jHKXzTbJgVMOb-jzan8lhmxQGSs_BAyCwMEk1MdRJ9XVVXQXjye80vqIYWVQJkHtBj0nYTSCzTe5jEhBdlGpwfMdGcBLrxUEVzD0RGhSeXt6CqHuREAKQllZ2h2_jfA6ehg",
"width": 2048
},
{
"height": 754,
"html_attributions": [
"Michalis Christofi"
],
"photo_reference": "CmRZAAAAYkuexUvSiG_tVssjPVw3BGsvDjobwD0gjkJKkUOXXEXXlKYi5nSzAjHO3xS7KRd8ZaB3UUj6RUI0IE30ZAecFxMBd-qmORQb5M6Zgt7UrXzpBh2hMlhjGhQdS7WaOQFYEhAhFE8dunrSxpP-jJggmQzDGhSVHHz583G50lFjnX6J0d00u3O6Nw",
"width": 639
},
{
"height": 1536,
"html_attributions": [
"Michalis Christofi"
],
"photo_reference": "CmRZAAAAEoDqdNive69uJD2elhZAs50tPQUbBVGJDwULsyEsiHK85pMrwvzjy26SZqXLj4NRB-8lyDxyoFn2oqp6KFlqOyWgwimzv-W3LJDEdlLuUq1-hfU-MgR3PuptbeVf56BYEhAP_3GFlHnFEPijFPt5vNCvGhSEMexeFrcqgLcegYYynFFw3XpytA",
"width": 2048
}
],
"place_id": "ChIJ022Et4sG5xQRtB0kHxBfakc",
"plus_code": {
"compound_code": "QCJP+C2 Paphos, Cyprus",
"global_code": "8G6JQCJP+C2"
},
"rating": 4.8,
"reference": "ChIJ022Et4sG5xQRtB0kHxBfakc",
"reviews": [
{
"author_name": "Bill Hax",
"author_url": "https://www.google.com/maps/contrib/100332769349142525953/reviews",
"language": "en",
"profile_photo_url": "https://lh5.googleusercontent.com/-7NYsnw_M3pY/AAAAAAAAAAI/AAAAAAAACLI/iCl3xCE-hyc/s128-c0x00000000-cc-rp-mo-ba3/photo.jpg",
"rating": 5,
"relative_time_description": "9 months ago",
"text": "Best cheesecake brownies u will have! ! We ship them to lebanon 😂",
"time": 1522390670
},
{
"author_name": "G. Nad.",
"author_url": "https://www.google.com/maps/contrib/110675617871447677660/reviews",
"profile_photo_url": "https://lh3.googleusercontent.com/-W3LviwY-xTM/AAAAAAAAAAI/AAAAAAAAAAA/AKxrwcahlmVGmqRH2R49tcb4WwwxWnIDgw/s128-c0x00000000-cc-rp-mo/photo.jpg",
"rating": 5,
"relative_time_description": "3 months ago",
"text": "",
"time": 1539151080
},
{
"author_name": "Christina Christofi",
"author_url": "https://www.google.com/maps/contrib/116812443860721124624/reviews",
"profile_photo_url": "https://lh5.googleusercontent.com/-DOM0y22sX7Q/AAAAAAAAAAI/AAAAAAAAAAA/AKxrwcYrhk3mTztA81u06_SSqr8YtmTsCg/s128-c0x00000000-cc-rp-mo/photo.jpg",
"rating": 5,
"relative_time_description": "5 months ago",
"text": "",
"time": 1532377587
},
{
"author_name": "Michalis Christofi",
"author_url": "https://www.google.com/maps/contrib/109749370461397405510/reviews",
"profile_photo_url": "https://lh4.googleusercontent.com/-llt-lt53Y4o/AAAAAAAAAAI/AAAAAAAAAAA/AKxrwcbc-3ZahfOATYxC7u8OAOBoo8EINQ/s128-c0x00000000-cc-rp-mo/photo.jpg",
"rating": 5,
"relative_time_description": "5 months ago",
"text": "",
"time": 1532359074
},
{
"author_name": "Nick F",
"author_url": "https://www.google.com/maps/contrib/107808115662805818674/reviews",
"profile_photo_url": "https://lh5.googleusercontent.com/-cuA4HtKIgZA/AAAAAAAAAAI/AAAAAAAAAAk/VqVcEUa9pYQ/s128-c0x00000000-cc-rp-mo-ba4/photo.jpg",
"rating": 4,
"relative_time_description": "a month ago",
"text": "",
"time": 1542667692
}
],
"scope": "GOOGLE",
"types": [
"bakery",
"store",
"point_of_interest",
"food",
"establishment"
],
"url": "https://maps.google.com/?cid=5146030047070789044",
"user_ratings_total": 6,
"utc_offset": 120,
"vicinity": "56, Ελευθέριου Βενιζέλου 8021, Πάφος",
"website": "http://www.newyorksweets.com.cy"
},
"status": "OK"
}
try
fields=address_component,adr_address,alt_id,formatted_address,geometry,icon,id,name,permanently_closed,photo,place_id,plus_code,scope,type,url,utc_offset,vicinity
If you spell a paramter wrong it gets ignored fileds != fields
I have the following error when I want to create a stack with cloudformation:
The following resource(s) failed to create: [ApiSyncLogsPost]. . Rollback requested by user.
CREATE_FAILED AWS::ApiGateway::Method ApiSyncLogsPost Integrations of type 'AWS_PROXY' currently only supports Lambda function and Firehose stream invocations. (Service: AmazonApiGateway; Status Code: 400; Error Code: BadRequestException; Request ID: 8bff48b0-93e4-11e8-a183-5de2b976f282)
I didn't find anything relevant regarding this error on google, when I search about it I just get a lot of AWS cloudformation documentation.
What I think is happening is that ApiSyncLogsPost resource is not defined properly, but the examples I found on the internet are similar.
What needs to be changed to solve that error?
Here is the cloudformation json:
{
"AWSTemplateFormatVersion": "2010-09-09",
"Metadata": {
"AWS::CloudFormation::Designer": {
"a73e3686-2291-49a2-b052-565c5f85a9c9": {
"size": {
"width": 60,
"height": 60
},
"position": {
"x": 270,
"y": 120
},
"z": 2,
"parent": "d68e59d4-72c0-425a-9b7b-227cbac3252d",
"embeds": []
},
"0665ec07-964b-4c90-86c5-5f7731cece7b": {
"size": {
"width": 60,
"height": 60
},
"position": {
"x": 420,
"y": 120
},
"z": 1,
"embeds": []
},
"d68e59d4-72c0-425a-9b7b-227cbac3252d": {
"size": {
"width": 300,
"height": 240
},
"position": {
"x": 60,
"y": 90
},
"z": 1,
"embeds": [
"a73e3686-2291-49a2-b052-565c5f85a9c9",
"2cefafdd-86fd-4cbe-b42e-c638a8c23a19"
],
"iscontainedinside": [
"a86c6b83-5254-4848-943e-db6e35f09bf6"
]
},
"2cefafdd-86fd-4cbe-b42e-c638a8c23a19": {
"size": {
"width": 60,
"height": 60
},
"position": {
"x": 60,
"y": 120
},
"z": 2,
"parent": "d68e59d4-72c0-425a-9b7b-227cbac3252d",
"embeds": [],
"iscontainedinside": [
"d68e59d4-72c0-425a-9b7b-227cbac3252d",
"d68e59d4-72c0-425a-9b7b-227cbac3252d",
"a86c6b83-5254-4848-943e-db6e35f09bf6"
]
},
"a86c6b83-5254-4848-943e-db6e35f09bf6": {
"size": {
"width": 330,
"height": 330
},
"position": {
"x": 510,
"y": 90
},
"z": 1,
"embeds": [
"66745c5a-f3ad-4b8c-b575-e90d73cbf19b",
"cf340921-6a8b-45f2-8a2a-14ffb0e537e8",
"925587cf-52b3-4507-9131-6be6777905fe"
]
},
"66745c5a-f3ad-4b8c-b575-e90d73cbf19b": {
"size": {
"width": 60,
"height": 60
},
"position": {
"x": 540,
"y": 150
},
"z": 2,
"parent": "a86c6b83-5254-4848-943e-db6e35f09bf6",
"embeds": [],
"iscontainedinside": [
"a86c6b83-5254-4848-943e-db6e35f09bf6"
]
},
"cf340921-6a8b-45f2-8a2a-14ffb0e537e8": {
"size": {
"width": 60,
"height": 60
},
"position": {
"x": 680,
"y": 200
},
"z": 2,
"parent": "a86c6b83-5254-4848-943e-db6e35f09bf6",
"embeds": [],
"iscontainedinside": [
"a86c6b83-5254-4848-943e-db6e35f09bf6"
]
},
"925587cf-52b3-4507-9131-6be6777905fe": {
"size": {
"width": 60,
"height": 60
},
"position": {
"x": 540,
"y": 270
},
"z": 2,
"parent": "a86c6b83-5254-4848-943e-db6e35f09bf6",
"embeds": [],
"iscontainedinside": [
"a86c6b83-5254-4848-943e-db6e35f09bf6"
],
"dependson": [
"2cefafdd-86fd-4cbe-b42e-c638a8c23a19"
]
}
}
},
"Parameters": {
"DatabaseUrl": {
"Description": "DATABASE_URL taken from elastic bean. Example: postgres://my_own_user:my_own_access#my_own_link.rds.amazonaws.com:PORT/my_database_name",
"Type": "String"
},
"LogentriesToken": {
"Description": "",
"Type": "String"
},
"RedisUrl": {
"Description": "",
"Type": "String"
},
"DeploymentStage": {
"Description": "",
"Type": "String",
"Default": "staging"
},
"StackResourcePrefix": {
"Description": "The name will be used to create all the resources that belongs to the same stack.",
"Default": "StagingSyncLogs",
"Type": "String"
}
},
"Resources": {
"ErrorCfn": {
"Type": "AWS::ApiGateway::Model",
"Properties": {
"ContentType": "application/json",
"Name": "ErrorCfn",
"RestApiId": {
"Ref": "SyncLogsApi"
},
"Schema": {
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Error Schema",
"type": "object",
"properties": {
"message": {
"type": "string"
}
}
}
},
"Metadata": {
"AWS::CloudFormation::Designer": {
"id": "cf340921-6a8b-45f2-8a2a-14ffb0e537e8"
}
}
},
"UserPropertyModel": {
"Type": "AWS::ApiGateway::Model",
"Properties": {
"ContentType": "application/json",
"Name": "UserPropertyModel",
"RestApiId": {
"Ref": "SyncLogsApi"
},
"Schema": {
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "UserPropertyModel",
"type": "object",
"properties": {
"Name": {
"type": "string"
}
}
}
},
"Metadata": {
"AWS::CloudFormation::Designer": {
"id": "66745c5a-f3ad-4b8c-b575-e90d73cbf19b"
}
}
},
"LambdaExecutionRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
"lambda.amazonaws.com"
]
},
"Action": [
"sts:AssumeRole"
]
}
]
},
"Path": "/",
"Policies": [
{
"PolicyName": "PolicyNameForLambdaRole",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Sid": "1",
"Effect": "Allow",
"Action": [
"lambda:InvokeFunction"
],
"Resource": [
"*"
]
},
{
"Sid": "2",
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": [
"*"
]
}
]
}
}
],
"RoleName": {
"Fn::Join": [
"_",
[
{
"Ref": "StackResourcePrefix"
},
"PostgresCron",
"Role"
]
]
}
},
"Metadata": {
"AWS::CloudFormation::Designer": {
"id": "0665ec07-964b-4c90-86c5-5f7731cece7b"
}
}
},
"SyncLogsLambda": {
"Type": "AWS::Lambda::Function",
"Properties": {
"Code": {
"S3Bucket": "myBucket456464",
"S3Key": "myCode34535.zip"
},
"Environment": {
"Variables": {
"DATABASE_URL": {
"Ref": "DatabaseUrl"
},
"LOGENTRIES_TOKEN": {
"Ref": "LogentriesToken"
},
"REDIS_URL": {
"Ref": "RedisUrl"
}
}
},
"Tags": [
{
"Key": "DeploymentStage",
"Value": {
"Ref": "DeploymentStage"
}
}
],
"FunctionName": {
"Fn::Join": [
"",
[
{
"Ref": "StackResourcePrefix"
},
"_",
"lambda"
]
]
},
"Description": "Lambda function for syncing logs to logentries",
"Handler": "index.handler",
"Runtime": "nodejs6.10",
"MemorySize": 128,
"Timeout": 300,
"Role": {
"Fn::GetAtt": [
"LambdaExecutionRole",
"Arn"
]
}
},
"Metadata": {
"AWS::CloudFormation::Designer": {
"id": "a73e3686-2291-49a2-b052-565c5f85a9c9"
}
}
},
"ProxyResource": {
"Type": "AWS::ApiGateway::Resource",
"Properties": {
"RestApiId": {
"Ref": "SyncLogsApi"
},
"ParentId": {
"Fn::GetAtt": [
"SyncLogsApi",
"RootResourceId"
]
},
"PathPart": "synclogs"
},
"Metadata": {
"AWS::CloudFormation::Designer": {
"id": "d68e59d4-72c0-425a-9b7b-227cbac3252d"
}
}
},
"SyncLogsApi": {
"Type": "AWS::ApiGateway::RestApi",
"Properties": {
"Name": "Sync logs Api",
"Description": "Sync logs when this link is called.",
"FailOnWarnings": true
},
"Metadata": {
"AWS::CloudFormation::Designer": {
"id": "a86c6b83-5254-4848-943e-db6e35f09bf6"
}
}
},
"ApiSyncLogsPost": {
"Type": "AWS::ApiGateway::Method",
"Properties": {
"ResourceId": {
"Ref": "ProxyResource"
},
"RestApiId": {
"Ref": "SyncLogsApi"
},
"HttpMethod": "POST",
"AuthorizationType": "NONE",
"Integration": {
"Type": "AWS_PROXY",
"IntegrationHttpMethod": "POST",
"Uri": {
"Fn::Join": [
"",
[
"arn:aws:apigateway:",
{
"Ref": "AWS::Region"
},
":lambda:path/2015-03-31/functions/",
{
"Fn::GetAtt": [
"SyncLogsLambda",
"Arn"
]
},
"/synclogs"
]
]
}
},
"MethodResponses": [
{
"ResponseModels": {
"application/json": {
"Ref": "UserPropertyModel"
}
},
"StatusCode": 200
},
{
"ResponseModels": {
"application/json": {
"Ref": "ErrorCfn"
}
},
"StatusCode": 404
},
{
"ResponseModels": {
"application/json": {
"Ref": "ErrorCfn"
}
},
"StatusCode": 500
}
]
},
"Metadata": {
"AWS::CloudFormation::Designer": {
"id": "2cefafdd-86fd-4cbe-b42e-c638a8c23a19"
}
}
},
"RestApiDeployment": {
"Type": "AWS::ApiGateway::Deployment",
"Properties": {
"RestApiId": {
"Ref": "SyncLogsApi"
},
"StageName": "Staging"
},
"DependsOn": [
"ApiSyncLogsPost"
],
"Metadata": {
"AWS::CloudFormation::Designer": {
"id": "925587cf-52b3-4507-9131-6be6777905fe"
}
}
}
}
}
The error is due to improper value for Integration.Uri in the ApiSyncLogsPost resource. The Uri should have the form:
arn:aws:apigateway:{region}:{subdomain.service|service}:path|action/{service_api}
Example:
arn:aws:apigateway:eu-west-1:lambda:path/2015-03-31/functions/arn:aws:lambda:eu-west-1:012345678901:function:MyLambda/invocations
In your case, the string "/synclogs" at the end which should actually be "/invocations"
The following Integration.Uri for ApiSyncLogsPost should fix the issue:
{
"Uri": {
"Fn::Join": [
"",
[
"arn:aws:apigateway:",
{
"Ref": "AWS::Region"
},
":lambda:path/2015-03-31/functions/",
{
"Fn::GetAtt": [
"SyncLogsLambda",
"Arn"
]
},
"/invocations"
]
]
}
}